1188 lines · 44.3 KB · Java
RawDownload
            setSize(alloc.width, alloc.height);        }        return super.viewToModel(x, y, a, bias);    }     /**     * Determines the desired alignment for this view along an     * axis.  This is implemented to give the total alignment     * needed to position the children with the alignment points     * lined up along the axis orthoginal to the axis that is     * being tiled.  The axis being tiled will request to be     * centered (i.e. 0.5f).     *     * @param axis may be either <code>View.X_AXIS</code>     *   or <code>View.Y_AXIS</code>     * @return the desired alignment >= 0.0f && <= 1.0f; this should     *   be a value between 0.0 and 1.0 where 0 indicates alignment at the     *   origin and 1.0 indicates alignment to the full span     *   away from the origin; an alignment of 0.5 would be the     *   center of the view     * @exception IllegalArgumentException for an invalid axis     */    public float getAlignment(int axis) {        checkRequests(axis);        if (axis == majorAxis) {            return majorRequest.alignment;        } else {            return minorRequest.alignment;        }    }     /**     * Determines the preferred span for this view along an     * axis.     *     * @param axis may be either <code>View.X_AXIS</code>     *           or <code>View.Y_AXIS</code>     * @return   the span the view would like to be rendered into >= 0;     *           typically the view is told to render into the span     *           that is returned, although there is no guarantee;     *           the parent may choose to resize or break the view     * @exception IllegalArgumentException for an invalid axis type     */    public float getPreferredSpan(int axis) {        checkRequests(axis);        float marginSpan = (axis == X_AXIS) ? getLeftInset() + getRightInset() :            getTopInset() + getBottomInset();        if (axis == majorAxis) {            return ((float)majorRequest.preferred) + marginSpan;        } else {            return ((float)minorRequest.preferred) + marginSpan;        }    }     /**     * Determines the minimum span for this view along an     * axis.     *     * @param axis may be either <code>View.X_AXIS</code>     *           or <code>View.Y_AXIS</code>     * @return  the span the view would like to be rendered into >= 0;     *           typically the view is told to render into the span     *           that is returned, although there is no guarantee;     *           the parent may choose to resize or break the view     * @exception IllegalArgumentException for an invalid axis type     */    public float getMinimumSpan(int axis) {        checkRequests(axis);        float marginSpan = (axis == X_AXIS) ? getLeftInset() + getRightInset() :            getTopInset() + getBottomInset();        if (axis == majorAxis) {            return ((float)majorRequest.minimum) + marginSpan;        } else {            return ((float)minorRequest.minimum) + marginSpan;        }    }     /**     * Determines the maximum span for this view along an     * axis.     *     * @param axis may be either <code>View.X_AXIS</code>     *           or <code>View.Y_AXIS</code>     * @return   the span the view would like to be rendered into >= 0;     *           typically the view is told to render into the span     *           that is returned, although there is no guarantee;     *           the parent may choose to resize or break the view     * @exception IllegalArgumentException for an invalid axis type     */    public float getMaximumSpan(int axis) {        checkRequests(axis);        float marginSpan = (axis == X_AXIS) ? getLeftInset() + getRightInset() :            getTopInset() + getBottomInset();        if (axis == majorAxis) {            return ((float)majorRequest.maximum) + marginSpan;        } else {            return ((float)minorRequest.maximum) + marginSpan;        }    }     // --- local methods ----------------------------------------------------     /**     * Are the allocations for the children still     * valid?     *     * @return true if allocations still valid     */    protected boolean isAllocationValid() {        return (majorAllocValid && minorAllocValid);    }     /**     * Determines if a point falls before an allocated region.     *     * @param x the X coordinate >= 0     * @param y the Y coordinate >= 0     * @param innerAlloc the allocated region; this is the area     *   inside of the insets     * @return true if the point lies before the region else false     */    protected boolean isBefore(int x, int y, Rectangle innerAlloc) {        if (majorAxis == View.X_AXIS) {            return (x < innerAlloc.x);        } else {            return (y < innerAlloc.y);        }    }     /**     * Determines if a point falls after an allocated region.     *     * @param x the X coordinate >= 0     * @param y the Y coordinate >= 0     * @param innerAlloc the allocated region; this is the area     *   inside of the insets     * @return true if the point lies after the region else false     */    protected boolean isAfter(int x, int y, Rectangle innerAlloc) {        if (majorAxis == View.X_AXIS) {            return (x > (innerAlloc.width + innerAlloc.x));        } else {            return (y > (innerAlloc.height + innerAlloc.y));        }    }     /**     * Fetches the child view at the given coordinates.     *     * @param x the X coordinate >= 0     * @param y the Y coordinate >= 0     * @param alloc the parents inner allocation on entry, which should     *   be changed to the childs allocation on exit     * @return the view     */    protected View getViewAtPoint(int x, int y, Rectangle alloc) {        int n = getViewCount();        if (majorAxis == View.X_AXIS) {            if (x < (alloc.x + majorOffsets[0])) {                childAllocation(0, alloc);                return getView(0);            }            for (int i = 0; i < n; i++) {                if (x < (alloc.x + majorOffsets[i])) {                    childAllocation(i - 1, alloc);                    return getView(i - 1);                }            }            childAllocation(n - 1, alloc);            return getView(n - 1);        } else {            if (y < (alloc.y + majorOffsets[0])) {                childAllocation(0, alloc);                return getView(0);            }            for (int i = 0; i < n; i++) {                if (y < (alloc.y + majorOffsets[i])) {                    childAllocation(i - 1, alloc);                    return getView(i - 1);                }            }            childAllocation(n - 1, alloc);            return getView(n - 1);        }    }     /**     * Allocates a region for a child view.     *     * @param index the index of the child view to     *   allocate, >= 0 && < getViewCount()     * @param alloc the allocated region     */    protected void childAllocation(int index, Rectangle alloc) {        alloc.x += getOffset(X_AXIS, index);        alloc.y += getOffset(Y_AXIS, index);        alloc.width = getSpan(X_AXIS, index);        alloc.height = getSpan(Y_AXIS, index);    }     /**     * Perform layout on the box     *     * @param width the width (inside of the insets) >= 0     * @param height the height (inside of the insets) >= 0     */    protected void layout(int width, int height) {        setSpanOnAxis(X_AXIS, width);        setSpanOnAxis(Y_AXIS, height);    }     /**     * Returns the current width of the box.  This is the width that     * it was last allocated.     * @return the current width of the box     */    public int getWidth() {        int span;        if (majorAxis == X_AXIS) {            span = majorSpan;        } else {            span = minorSpan;        }        span += getLeftInset() - getRightInset();        return span;    }     /**     * Returns the current height of the box.  This is the height that     * it was last allocated.     * @return the current height of the box     */    public int getHeight() {        int span;        if (majorAxis == Y_AXIS) {            span = majorSpan;        } else {            span = minorSpan;        }        span += getTopInset() - getBottomInset();        return span;    }     /**     * Performs layout for the major axis of the box (i.e. the     * axis that it represents). The results of the layout (the     * offset and span for each children) are placed in the given     * arrays which represent the allocations to the children     * along the major axis.     *     * @param targetSpan the total span given to the view, which     *  would be used to layout the children     * @param axis the axis being layed out     * @param offsets the offsets from the origin of the view for     *  each of the child views; this is a return value and is     *  filled in by the implementation of this method     * @param spans the span of each child view; this is a return     *  value and is filled in by the implementation of this method     */    protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {        /*         * first pass, calculate the preferred sizes         * and the flexibility to adjust the sizes.         */        long preferred = 0;        int n = getViewCount();        for (int i = 0; i < n; i++) {            View v = getView(i);            spans[i] = (int) v.getPreferredSpan(axis);            preferred += spans[i];        }         /*         * Second pass, expand or contract by as much as possible to reach         * the target span.         */         // determine the adjustment to be made        long desiredAdjustment = targetSpan - preferred;        float adjustmentFactor = 0.0f;        int[] diffs = null;         if (desiredAdjustment != 0) {            long totalSpan = 0;            diffs = new int[n];            for (int i = 0; i < n; i++) {                View v = getView(i);                int tmp;                if (desiredAdjustment < 0) {                    tmp = (int)v.getMinimumSpan(axis);                    diffs[i] = spans[i] - tmp;                } else {                    tmp = (int)v.getMaximumSpan(axis);                    diffs[i] = tmp - spans[i];                }                totalSpan += tmp;            }             float maximumAdjustment = Math.abs(totalSpan - preferred);                adjustmentFactor = desiredAdjustment / maximumAdjustment;                adjustmentFactor = Math.min(adjustmentFactor, 1.0f);                adjustmentFactor = Math.max(adjustmentFactor, -1.0f);            }         // make the adjustments        int totalOffset = 0;        for (int i = 0; i < n; i++) {            offsets[i] = totalOffset;            if (desiredAdjustment != 0) {                float adjF = adjustmentFactor * diffs[i];                spans[i] += Math.round(adjF);            }            totalOffset = (int) Math.min((long) totalOffset + (long) spans[i], Integer.MAX_VALUE);        }    }     /**     * Performs layout for the minor axis of the box (i.e. the     * axis orthoginal to the axis that it represents). The results     * of the layout (the offset and span for each children) are     * placed in the given arrays which represent the allocations to     * the children along the minor axis.     *     * @param targetSpan the total span given to the view, which     *  would be used to layout the children     * @param axis the axis being layed out     * @param offsets the offsets from the origin of the view for     *  each of the child views; this is a return value and is     *  filled in by the implementation of this method     * @param spans the span of each child view; this is a return     *  value and is filled in by the implementation of this method     */    protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {        int n = getViewCount();        for (int i = 0; i < n; i++) {            View v = getView(i);            int max = (int) v.getMaximumSpan(axis);            if (max < targetSpan) {                // can't make the child this wide, align it                float align = v.getAlignment(axis);                offsets[i] = (int) ((targetSpan - max) * align);                spans[i] = max;            } else {                // make it the target width, or as small as it can get.                int min = (int)v.getMinimumSpan(axis);                offsets[i] = 0;                spans[i] = Math.max(min, targetSpan);            }        }    }     /**     * Calculates the size requirements for the major axis     * <code>axis</code>.     *     * @param axis the axis being studied     * @param r the <code>SizeRequirements</code> object;     *          if <code>null</code> one will be created     * @return the newly initialized <code>SizeRequirements</code> object     * @see javax.swing.SizeRequirements     */    protected SizeRequirements calculateMajorAxisRequirements(int axis, SizeRequirements r) {        // calculate tiled request        float min = 0;        float pref = 0;        float max = 0;         int n = getViewCount();        for (int i = 0; i < n; i++) {            View v = getView(i);            min += v.getMinimumSpan(axis);            pref += v.getPreferredSpan(axis);            max += v.getMaximumSpan(axis);        }         if (r == null) {            r = new SizeRequirements();        }        r.alignment = 0.5f;        r.minimum = (int) min;        r.preferred = (int) pref;        r.maximum = (int) max;        return r;    }     /**     * Calculates the size requirements for the minor axis     * <code>axis</code>.     *     * @param axis the axis being studied     * @param r the <code>SizeRequirements</code> object;     *          if <code>null</code> one will be created     * @return the newly initialized <code>SizeRequirements</code> object     * @see javax.swing.SizeRequirements     */    protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {        int min = 0;        long pref = 0;        int max = Integer.MAX_VALUE;        int n = getViewCount();        for (int i = 0; i < n; i++) {            View v = getView(i);            min = Math.max((int) v.getMinimumSpan(axis), min);            pref = Math.max((int) v.getPreferredSpan(axis), pref);            max = Math.max((int) v.getMaximumSpan(axis), max);        }         if (r == null) {            r = new SizeRequirements();            r.alignment = 0.5f;        }        r.preferred = (int) pref;        r.minimum = min;        r.maximum = max;        return r;    }     /**     * Checks the request cache and update if needed.     * @param axis the axis being studied     * @exception IllegalArgumentException if <code>axis</code> is     *  neither <code>View.X_AXIS</code> nor <code>View.Y_AXIS</code>     */    void checkRequests(int axis) {        if ((axis != X_AXIS) && (axis != Y_AXIS)) {            throw new IllegalArgumentException("Invalid axis: " + axis);        }        if (axis == majorAxis) {            if (!majorReqValid) {                majorRequest = calculateMajorAxisRequirements(axis,                                                              majorRequest);                majorReqValid = true;            }        } else if (! minorReqValid) {            minorRequest = calculateMinorAxisRequirements(axis, minorRequest);            minorReqValid = true;        }    }     /**     * Computes the location and extent of each child view     * in this <code>BoxView</code> given the <code>targetSpan</code>,     * which is the width (or height) of the region we have to     * work with.     *     * @param targetSpan the total span given to the view, which     *  would be used to layout the children     * @param axis the axis being studied, either     *          <code>View.X_AXIS</code> or <code>View.Y_AXIS</code>     * @param offsets an empty array filled by this method with     *          values specifying the location  of each child view     * @param spans  an empty array filled by this method with     *          values specifying the extent of each child view     */    protected void baselineLayout(int targetSpan, int axis, int[] offsets, int[] spans) {        int totalAscent = (int)(targetSpan * getAlignment(axis));        int totalDescent = targetSpan - totalAscent;         int n = getViewCount();         for (int i = 0; i < n; i++) {            View v = getView(i);            float align = v.getAlignment(axis);            float viewSpan;             if (v.getResizeWeight(axis) > 0) {                // if resizable then resize to the best fit                 // the smallest span possible                float minSpan = v.getMinimumSpan(axis);                // the largest span possible                float maxSpan = v.getMaximumSpan(axis);                 if (align == 0.0f) {                    // if the alignment is 0 then we need to fit into the descent                    viewSpan = Math.max(Math.min(maxSpan, totalDescent), minSpan);                } else if (align == 1.0f) {                    // if the alignment is 1 then we need to fit into the ascent                    viewSpan = Math.max(Math.min(maxSpan, totalAscent), minSpan);                } else {                    // figure out the span that we must fit into                    float fitSpan = Math.min(totalAscent / align,                                             totalDescent / (1.0f - align));                    // fit into the calculated span                    viewSpan = Math.max(Math.min(maxSpan, fitSpan), minSpan);                }            } else {                // otherwise use the preferred spans                viewSpan = v.getPreferredSpan(axis);            }             offsets[i] = totalAscent - (int)(viewSpan * align);            spans[i] = (int)viewSpan;        }    }     /**     * Calculates the size requirements for this <code>BoxView</code>     * by examining the size of each child view.     *

Lines 501–1000 of 1188. Previous lines