3745 lines · 140.5 KB · Java
RawDownload
                    (max < 0 && max != DEFAULT_SIZE && max != PREFERRED_SIZE)||                    (pref >= 0 && max >= 0 && pref > max)) {                throw new IllegalArgumentException(                        "Pref and max must be either DEFAULT_VALUE " +                        "or >= 0 and pref <= max");            }            hasPreferredPaddingSprings = true;            return (SequentialGroup)addSpring(                    new ContainerAutoPreferredGapSpring(pref, max));        }         int operator(int a, int b) {            return constrain(a) + constrain(b);        }         void setValidSize(int axis, int origin, int size) {            int pref = getPreferredSize(axis);            if (size == pref) {                // Layout at preferred size                for (Spring spring : springs) {                    int springPref = spring.getPreferredSize(axis);                    spring.setSize(axis, origin, springPref);                    origin += springPref;                }            } else if (springs.size() == 1) {                Spring spring = getSpring(0);                spring.setSize(axis, origin, Math.min(                        Math.max(size, spring.getMinimumSize(axis)),                        spring.getMaximumSize(axis)));            } else if (springs.size() > 1) {                // Adjust between min/pref                setValidSizeNotPreferred(axis, origin, size);            }        }         private void setValidSizeNotPreferred(int axis, int origin, int size) {            int delta = size - getPreferredSize(axis);            assert delta != 0;            boolean useMin = (delta < 0);            int springCount = springs.size();            if (useMin) {                delta *= -1;            }             // The following algorithm if used for resizing springs:            // 1. Calculate the resizability of each spring (pref - min or            //    max - pref) into a list.            // 2. Sort the list in ascending order            // 3. Iterate through each of the resizable Springs, attempting            //    to give them (pref - size) / resizeCount            // 4. For any Springs that can not accomodate that much space            //    add the remainder back to the amount to distribute and            //    recalculate how must space the remaining springs will get.            // 5. Set the size of the springs.             // First pass, sort the resizable springs into the List resizable            List<SpringDelta> resizable = buildResizableList(axis, useMin);            int resizableCount = resizable.size();             if (resizableCount > 0) {                // How much we would like to give each Spring.                int sDelta = delta / resizableCount;                // Remaining space.                int slop = delta - sDelta * resizableCount;                int[] sizes = new int[springCount];                int sign = useMin ? -1 : 1;                // Second pass, accumulate the resulting deltas (relative to                // preferred) into sizes.                for (int counter = 0; counter < resizableCount; counter++) {                    SpringDelta springDelta = resizable.get(counter);                    if ((counter + 1) == resizableCount) {                        sDelta += slop;                    }                    springDelta.delta = Math.min(sDelta, springDelta.delta);                    delta -= springDelta.delta;                    if (springDelta.delta != sDelta && counter + 1 <                            resizableCount) {                        // Spring didn't take all the space, reset how much                        // each spring will get.                        sDelta = delta / (resizableCount - counter - 1);                        slop = delta - sDelta * (resizableCount - counter - 1);                    }                    sizes[springDelta.index] = sign * springDelta.delta;                }                 // And finally set the size of each spring                for (int counter = 0; counter < springCount; counter++) {                    Spring spring = getSpring(counter);                    int sSize = spring.getPreferredSize(axis) + sizes[counter];                    spring.setSize(axis, origin, sSize);                    origin += sSize;                }            } else {                // Nothing resizable, use the min or max of each of the                // springs.                for (int counter = 0; counter < springCount; counter++) {                    Spring spring = getSpring(counter);                    int sSize;                    if (useMin) {                        sSize = spring.getMinimumSize(axis);                    } else {                        sSize = spring.getMaximumSize(axis);                    }                    spring.setSize(axis, origin, sSize);                    origin += sSize;                }            }        }         /**         * Returns the sorted list of SpringDelta's for the current set of         * Springs. The list is ordered based on the amount of flexibility of         * the springs.         */        private List<SpringDelta> buildResizableList(int axis,                boolean useMin) {            // First pass, figure out what is resizable            int size = springs.size();            List<SpringDelta> sorted = new ArrayList<SpringDelta>(size);            for (int counter = 0; counter < size; counter++) {                Spring spring = getSpring(counter);                int sDelta;                if (useMin) {                    sDelta = spring.getPreferredSize(axis) -                            spring.getMinimumSize(axis);                } else {                    sDelta = spring.getMaximumSize(axis) -                            spring.getPreferredSize(axis);                }                if (sDelta > 0) {                    sorted.add(new SpringDelta(counter, sDelta));                }            }            Collections.sort(sorted);            return sorted;        }         private int indexOfNextNonZeroSpring(                int index, boolean treatAutopaddingAsZeroSized) {            while (index < springs.size()) {                Spring spring = springs.get(index);                if (!spring.willHaveZeroSize(treatAutopaddingAsZeroSized)) {                    return index;                }                index++;            }            return index;        }         @Override        void insertAutopadding(int axis,                List<AutoPreferredGapSpring> leadingPadding,                List<AutoPreferredGapSpring> trailingPadding,                List<ComponentSpring> leading, List<ComponentSpring> trailing,                boolean insert) {            List<AutoPreferredGapSpring> newLeadingPadding =                    new ArrayList<AutoPreferredGapSpring>(leadingPadding);            List<AutoPreferredGapSpring> newTrailingPadding =                    new ArrayList<AutoPreferredGapSpring>(1);            List<ComponentSpring> newLeading =                    new ArrayList<ComponentSpring>(leading);            List<ComponentSpring> newTrailing = null;            int counter = 0;            // Warning, this must use springs.size, as it may change during the            // loop.            while (counter < springs.size()) {                Spring spring = getSpring(counter);                if (spring instanceof AutoPreferredGapSpring) {                    if (newLeadingPadding.size() == 0) {                        // Autopadding spring. Set the sources of the                        // autopadding spring based on newLeading.                        AutoPreferredGapSpring padding =                            (AutoPreferredGapSpring)spring;                        padding.setSources(newLeading);                        newLeading.clear();                        counter = indexOfNextNonZeroSpring(counter + 1, true);                        if (counter == springs.size()) {                            // Last spring in the list, add it to                            // trailingPadding.                            if (!(padding instanceof                                  ContainerAutoPreferredGapSpring)) {                                trailingPadding.add(padding);                            }                        } else {                            newLeadingPadding.clear();                            newLeadingPadding.add(padding);                        }                    } else {                        counter = indexOfNextNonZeroSpring(counter + 1, true);                    }                } else {                    // Not a padding spring                    if (newLeading.size() > 0 && insert) {                        // There's leading ComponentSprings, create an                        // autopadding spring.                        AutoPreferredGapSpring padding =                                new AutoPreferredGapSpring();                        // Force the newly created spring to be considered                        // by NOT incrementing counter                        springs.add(counter, padding);                        continue;                    }                    if (spring instanceof ComponentSpring) {                        // Spring is a Component, make it the target of any                        // leading AutopaddingSpring.                        ComponentSpring cSpring = (ComponentSpring)spring;                        if (!cSpring.isVisible()) {                            counter++;                            continue;                        }                        for (AutoPreferredGapSpring gapSpring : newLeadingPadding) {                            gapSpring.addTarget(cSpring, axis);                        }                        newLeading.clear();                        newLeadingPadding.clear();                        counter = indexOfNextNonZeroSpring(counter + 1, false);                        if (counter == springs.size()) {                            // Last Spring, add it to trailing                            trailing.add(cSpring);                        } else {                            // Not that last Spring, add it to leading                            newLeading.add(cSpring);                        }                    } else if (spring instanceof Group) {                        // Forward call to child Group                        if (newTrailing == null) {                            newTrailing = new ArrayList<ComponentSpring>(1);                        } else {                            newTrailing.clear();                        }                        newTrailingPadding.clear();                        ((Group)spring).insertAutopadding(axis,                                newLeadingPadding, newTrailingPadding,                                newLeading, newTrailing, insert);                        newLeading.clear();                        newLeadingPadding.clear();                        counter = indexOfNextNonZeroSpring(                                    counter + 1, (newTrailing.size() == 0));                        if (counter == springs.size()) {                            trailing.addAll(newTrailing);                            trailingPadding.addAll(newTrailingPadding);                        } else {                            newLeading.addAll(newTrailing);                            newLeadingPadding.addAll(newTrailingPadding);                        }                    } else {                        // Gap                        newLeadingPadding.clear();                        newLeading.clear();                        counter++;                    }                }            }        }         int getBaseline() {            if (baselineSpring != null) {                int baseline = baselineSpring.getBaseline();                if (baseline >= 0) {                    int size = 0;                    for (Spring spring : springs) {                        if (spring == baselineSpring) {                            return size + baseline;                        } else {                            size += spring.getPreferredSize(VERTICAL);                        }                    }                }            }            return -1;        }         BaselineResizeBehavior getBaselineResizeBehavior() {            if (isResizable(VERTICAL)) {                if (!baselineSpring.isResizable(VERTICAL)) {                    // Spring to use for baseline isn't resizable. In this case                    // baseline resize behavior can be determined based on how                    // preceeding springs resize.                    boolean leadingResizable = false;                    for (Spring spring : springs) {                        if (spring == baselineSpring) {                            break;                        } else if (spring.isResizable(VERTICAL)) {                            leadingResizable = true;                            break;                        }                    }                    boolean trailingResizable = false;                    for (int i = springs.size() - 1; i >= 0; i--) {                        Spring spring = springs.get(i);                        if (spring == baselineSpring) {                            break;                        }                        if (spring.isResizable(VERTICAL)) {                            trailingResizable = true;                            break;                        }                    }                    if (leadingResizable && !trailingResizable) {                        return BaselineResizeBehavior.CONSTANT_DESCENT;                    } else if (!leadingResizable && trailingResizable) {                        return BaselineResizeBehavior.CONSTANT_ASCENT;                    }                    // If we get here, both leading and trailing springs are                    // resizable. Fall through to OTHER.                } else {                    BaselineResizeBehavior brb = baselineSpring.getBaselineResizeBehavior();                    if (brb == BaselineResizeBehavior.CONSTANT_ASCENT) {                        for (Spring spring : springs) {                            if (spring == baselineSpring) {                                return BaselineResizeBehavior.CONSTANT_ASCENT;                            }                            if (spring.isResizable(VERTICAL)) {                                return BaselineResizeBehavior.OTHER;                            }                        }                    } else if (brb == BaselineResizeBehavior.CONSTANT_DESCENT) {                        for (int i = springs.size() - 1; i >= 0; i--) {                            Spring spring = springs.get(i);                            if (spring == baselineSpring) {                                return BaselineResizeBehavior.CONSTANT_DESCENT;                            }                            if (spring.isResizable(VERTICAL)) {                                return BaselineResizeBehavior.OTHER;                            }                        }                    }                }                return BaselineResizeBehavior.OTHER;            }            // Not resizable, treat as constant_ascent            return BaselineResizeBehavior.CONSTANT_ASCENT;        }         private void checkPreferredGapValues(int pref, int max) {            if ((pref < 0 && pref != DEFAULT_SIZE && pref != PREFERRED_SIZE) ||                    (max < 0 && max != DEFAULT_SIZE && max != PREFERRED_SIZE)||                    (pref >= 0 && max >= 0 && pref > max)) {                throw new IllegalArgumentException(                        "Pref and max must be either DEFAULT_SIZE, " +                        "PREFERRED_SIZE, or >= 0 and pref <= max");            }        }    }      /**     * Used by SequentialGroup in calculating resizability of springs.     */    private static final class SpringDelta implements Comparable<SpringDelta> {        // Original index.        public final int index;        // Delta, one of pref - min or max - pref.        public int delta;         public SpringDelta(int index, int delta) {            this.index = index;            this.delta = delta;        }         public int compareTo(SpringDelta o) {            return delta - o.delta;        }         public String toString() {            return super.toString() + "[index=" + index + ", delta=" +                    delta + "]";        }    }      /**     * A {@code Group} that aligns and sizes it's children.     * {@code ParallelGroup} aligns it's children in     * four possible ways: along the baseline, centered, anchored to the     * leading edge, or anchored to the trailing edge.     * <h3>Baseline</h3>     * A {@code ParallelGroup} that aligns it's children along the     * baseline must first decide where the baseline is     * anchored. The baseline can either be anchored to the top, or     * anchored to the bottom of the group. That is, the distance between the     * baseline and the beginning of the group can be a constant     * distance, or the distance between the end of the group and the     * baseline can be a constant distance. The possible choices     * correspond to the {@code BaselineResizeBehavior} constants     * {@link     * java.awt.Component.BaselineResizeBehavior#CONSTANT_ASCENT CONSTANT_ASCENT} and     * {@link     * java.awt.Component.BaselineResizeBehavior#CONSTANT_DESCENT CONSTANT_DESCENT}.     * <p>     * The baseline anchor may be explicitly specified by the     * {@code createBaselineGroup} method, or determined based on the elements.     * If not explicitly specified, the baseline will be anchored to     * the bottom if all the elements with a baseline, and that are     * aligned to the baseline, have a baseline resize behavior of     * {@code CONSTANT_DESCENT}; otherwise the baseline is anchored to the top     * of the group.     * <p>     * Elements aligned to the baseline are resizable if they have have     * a baseline resize behavior of {@code CONSTANT_ASCENT} or     * {@code CONSTANT_DESCENT}. Elements with a baseline resize     * behavior of {@code OTHER} or {@code CENTER_OFFSET} are not resizable.     * <p>     * The baseline is calculated based on the preferred height of each     * of the elements that have a baseline. The baseline is     * calculated using the following algorithm:     * {@code max(maxNonBaselineHeight, maxAscent + maxDescent)}, where the     * {@code maxNonBaselineHeight} is the maximum height of all elements     * that do not have a baseline, or are not aligned along the baseline.     * {@code maxAscent} is the maximum ascent (baseline) of all elements that     * have a baseline and are aligned along the baseline.     * {@code maxDescent} is the maximum descent (preferred height - baseline)     * of all elements that have a baseline and are aligned along the baseline.     * <p>     * A {@code ParallelGroup} that aligns it's elements along the baseline     * is only useful along the vertical axis. If you create a     * baseline group and use it along the horizontal axis an     * {@code IllegalStateException} is thrown when you ask     * {@code GroupLayout} for the minimum, preferred or maximum size or     * attempt to layout the components.     * <p>     * Elements that are not aligned to the baseline and smaller than the size     * of the {@code ParallelGroup} are positioned in one of three     * ways: centered, anchored to the leading edge, or anchored to the     * trailing edge.     *     * <h3>Non-baseline {@code ParallelGroup}</h3>     * {@code ParallelGroup}s created with an alignment other than     * {@code BASELINE} align elements that are smaller than the size     * of the group in one of three ways: centered, anchored to the     * leading edge, or anchored to the trailing edge.     * <p>     * The leading edge is based on the axis and {@code     * ComponentOrientation}.  For the vertical axis the top edge is     * always the leading edge, and the bottom edge is always the     * trailing edge. When the {@code ComponentOrientation} is {@code     * LEFT_TO_RIGHT}, the leading edge is the left edge and the     * trailing edge the right edge. A {@code ComponentOrientation} of     * {@code RIGHT_TO_LEFT} flips the left and right edges. Child     * elements are aligned based on the specified alignment the     * element was added with. If you do not specify an alignment, the     * alignment specified for the {@code ParallelGroup} is used.     * <p>     * To align elements along the baseline you {@code createBaselineGroup},     * or {@code createParallelGroup} with an alignment of {@code BASELINE}.     * If the group was not created with a baseline alignment, and you attempt     * to add an element specifying a baseline alignment, an     * {@code IllegalArgumentException} is thrown.     *     * @see #createParallelGroup()     * @see #createBaselineGroup(boolean,boolean)     * @since 1.6     */    public class ParallelGroup extends Group {        // How children are layed out.        private final Alignment childAlignment;        // Whether or not we're resizable.        private final boolean resizable;         ParallelGroup(Alignment childAlignment, boolean resizable) {            this.childAlignment = childAlignment;            this.resizable = resizable;        }         /**         * {@inheritDoc}         */        public ParallelGroup addGroup(Group group) {            return (ParallelGroup)super.addGroup(group);        }         /**         * {@inheritDoc}         */        public ParallelGroup addComponent(Component component) {            return (ParallelGroup)super.addComponent(component);        }         /**         * {@inheritDoc}         */        public ParallelGroup addComponent(Component component, int min, int pref,                int max) {            return (ParallelGroup)super.addComponent(component, min, pref, max);        }         /**         * {@inheritDoc}         */        public ParallelGroup addGap(int pref) {            return (ParallelGroup)super.addGap(pref);        }         /**         * {@inheritDoc}         */        public ParallelGroup addGap(int min, int pref, int max) {            return (ParallelGroup)super.addGap(min, pref, max);        } 

Lines 2001–2500 of 3745. Previous lines