diff options
Diffstat (limited to 'libjava/classpath/javax/swing/text/BoxView.java')
-rw-r--r-- | libjava/classpath/javax/swing/text/BoxView.java | 1112 |
1 files changed, 0 insertions, 1112 deletions
diff --git a/libjava/classpath/javax/swing/text/BoxView.java b/libjava/classpath/javax/swing/text/BoxView.java deleted file mode 100644 index 325364d..0000000 --- a/libjava/classpath/javax/swing/text/BoxView.java +++ /dev/null @@ -1,1112 +0,0 @@ -/* BoxView.java -- An composite view - Copyright (C) 2005, 2006 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package javax.swing.text; - -import java.awt.Container; -import java.awt.Graphics; -import java.awt.Rectangle; -import java.awt.Shape; - -import javax.swing.SizeRequirements; -import javax.swing.event.DocumentEvent; - -/** - * An implementation of {@link CompositeView} that arranges its children in - * a box along one axis. This is comparable to how the <code>BoxLayout</code> - * works, but for <code>View</code> children. - * - * @author Roman Kennke (roman@kennke.org) - */ -public class BoxView - extends CompositeView -{ - - /** - * The axis along which this <code>BoxView</code> is laid out. - */ - private int myAxis; - - /** - * Indicates if the layout is valid along X_AXIS or Y_AXIS. - */ - private boolean[] layoutValid = new boolean[2]; - - /** - * Indicates if the requirements for an axis are valid. - */ - private boolean[] requirementsValid = new boolean[2]; - - /** - * The spans along the X_AXIS and Y_AXIS. - */ - private int[][] spans = new int[2][]; - - /** - * The offsets of the children along the X_AXIS and Y_AXIS. - */ - private int[][] offsets = new int[2][]; - - /** - * The size requirements along the X_AXIS and Y_AXIS. - */ - private SizeRequirements[] requirements = new SizeRequirements[2]; - - /** - * The current span along X_AXIS or Y_AXIS. - */ - private int[] span = new int[2]; - - /** - * Creates a new <code>BoxView</code> for the given - * <code>Element</code> and axis. Valid values for the axis are - * {@link View#X_AXIS} and {@link View#Y_AXIS}. - * - * @param element the element that is rendered by this BoxView - * @param axis the axis along which the box is laid out - */ - public BoxView(Element element, int axis) - { - super(element); - myAxis = axis; - layoutValid[0] = false; - layoutValid[1] = false; - requirementsValid[X_AXIS] = false; - requirementsValid[Y_AXIS] = false; - span[0] = 0; - span[1] = 0; - requirements[0] = new SizeRequirements(); - requirements[1] = new SizeRequirements(); - - // Initialize the cache arrays. - spans[0] = new int[0]; - spans[1] = new int[0]; - offsets[0] = new int[0]; - offsets[1] = new int[0]; - } - - /** - * Returns the axis along which this <code>BoxView</code> is laid out. - * - * @return the axis along which this <code>BoxView</code> is laid out - * - * @since 1.3 - */ - public int getAxis() - { - return myAxis; - } - - /** - * Sets the axis along which this <code>BoxView</code> is laid out. - * - * Valid values for the axis are {@link View#X_AXIS} and - * {@link View#Y_AXIS}. - * - * @param axis the axis along which this <code>BoxView</code> is laid out - * - * @since 1.3 - */ - public void setAxis(int axis) - { - boolean changed = axis != myAxis; - myAxis = axis; - if (changed) - preferenceChanged(null, true, true); - } - - /** - * Marks the layout along the specified axis as invalid. This is triggered - * automatically when any of the child view changes its preferences - * via {@link #preferenceChanged(View, boolean, boolean)}. - * - * The layout will be updated the next time when - * {@link #setSize(float, float)} is called, typically from within the - * {@link #paint(Graphics, Shape)} method. - * - * Valid values for the axis are {@link View#X_AXIS} and - * {@link View#Y_AXIS}. - * - * @param axis an <code>int</code> value - * - * @since 1.3 - */ - public void layoutChanged(int axis) - { - if (axis != X_AXIS && axis != Y_AXIS) - throw new IllegalArgumentException("Invalid axis parameter."); - layoutValid[axis] = false; - } - - /** - * Returns <code>true</code> if the layout along the specified - * <code>axis</code> is valid, <code>false</code> otherwise. - * - * Valid values for the axis are {@link View#X_AXIS} and - * {@link View#Y_AXIS}. - * - * @param axis the axis - * - * @return <code>true</code> if the layout along the specified - * <code>axis</code> is valid, <code>false</code> otherwise - * - * @since 1.4 - */ - protected boolean isLayoutValid(int axis) - { - if (axis != X_AXIS && axis != Y_AXIS) - throw new IllegalArgumentException("Invalid axis parameter."); - return layoutValid[axis]; - } - - /** - * Paints the child <code>View</code> at the specified <code>index</code>. - * This method modifies the actual values in <code>alloc</code> so make - * sure you have a copy of the original values if you need them. - * - * @param g the <code>Graphics</code> context to paint to - * @param alloc the allocated region for the child to paint into - * @param index the index of the child to be painted - * - * @see #childAllocation(int, Rectangle) - */ - protected void paintChild(Graphics g, Rectangle alloc, int index) - { - View child = getView(index); - child.paint(g, alloc); - } - - /** - * Replaces child views by some other child views. If there are no views to - * remove (<code>length == 0</code>), the result is a simple insert, if - * there are no children to add (<code>view == null</code>) the result - * is a simple removal. - * - * In addition this invalidates the layout and resizes the internal cache - * for the child allocations. The old children's cached allocations can - * still be accessed (although they are not guaranteed to be valid), and - * the new children will have an initial offset and span of 0. - * - * @param offset the start offset from where to remove children - * @param length the number of children to remove - * @param views the views that replace the removed children - */ - public void replace(int offset, int length, View[] views) - { - // Actually perform the replace. - super.replace(offset, length, views); - - // Resize and copy data for cache arrays. - int newItems = views != null ? views.length : 0; - int minor = 1 - myAxis; - offsets[myAxis] = replaceLayoutArray(offsets[myAxis], offset, newItems); - spans[myAxis] = replaceLayoutArray(spans[myAxis], offset, newItems); - layoutValid[myAxis] = false; - requirementsValid[myAxis] = false; - offsets[minor] = replaceLayoutArray(offsets[minor], offset, newItems); - spans[minor] = replaceLayoutArray(spans[minor], offset, newItems); - layoutValid[minor] = false; - requirementsValid[minor] = false; - } - - /** - * Helper method. This updates the layout cache arrays in response - * to a call to {@link #replace(int, int, View[])}. - * - * @param oldArray the old array - * - * @return the replaced array - */ - private int[] replaceLayoutArray(int[] oldArray, int offset, int newItems) - - { - int num = getViewCount(); - int[] newArray = new int[num]; - System.arraycopy(oldArray, 0, newArray, 0, offset); - System.arraycopy(oldArray, offset, newArray, offset + newItems, - num - newItems - offset); - return newArray; - } - - /** - * A Rectangle instance to be reused in the paint() method below. - */ - private final Rectangle tmpRect = new Rectangle(); - - private Rectangle clipRect = new Rectangle(); - - /** - * Renders the <code>Element</code> that is associated with this - * <code>View</code>. - * - * @param g the <code>Graphics</code> context to render to - * @param a the allocated region for the <code>Element</code> - */ - public void paint(Graphics g, Shape a) - { - // Try to avoid allocation if possible (almost all cases). - Rectangle alloc = a instanceof Rectangle ? (Rectangle) a : a.getBounds(); - - // This returns a cached instance. - alloc = getInsideAllocation(alloc); - - int count = getViewCount(); - for (int i = 0; i < count; i++) - { - View child = getView(i); - tmpRect.setBounds(alloc); - childAllocation(i, tmpRect); - if (g.hitClip(tmpRect.x, tmpRect.y, tmpRect.width, tmpRect.height)) - paintChild(g, tmpRect, i); - } - } - - /** - * Returns the preferred span of the content managed by this - * <code>View</code> along the specified <code>axis</code>. - * - * @param axis the axis - * - * @return the preferred span of this <code>View</code>. - */ - public float getPreferredSpan(int axis) - { - updateRequirements(axis); - // Add margin. - float margin; - if (axis == X_AXIS) - margin = getLeftInset() + getRightInset(); - else - margin = getTopInset() + getBottomInset(); - return requirements[axis].preferred + margin; - } - - /** - * Returns the maximum span of this view along the specified axis. - * This returns <code>Integer.MAX_VALUE</code> for the minor axis - * and the preferred span for the major axis. - * - * @param axis the axis - * - * @return the maximum span of this view along the specified axis - */ - public float getMaximumSpan(int axis) - { - updateRequirements(axis); - // Add margin. - float margin; - if (axis == X_AXIS) - margin = getLeftInset() + getRightInset(); - else - margin = getTopInset() + getBottomInset(); - return requirements[axis].maximum + margin; - } - - /** - * Returns the minimum span of this view along the specified axis. - * This calculates the minimum span using - * {@link #calculateMajorAxisRequirements} or - * {@link #calculateMinorAxisRequirements} (depending on the axis) and - * returns the resulting minimum span. - * - * @param axis the axis - * - * @return the minimum span of this view along the specified axis - */ - public float getMinimumSpan(int axis) - { - updateRequirements(axis); - // Add margin. - float margin; - if (axis == X_AXIS) - margin = getLeftInset() + getRightInset(); - else - margin = getTopInset() + getBottomInset(); - return requirements[axis].minimum + margin; - } - - /** - * Calculates size requirements for a baseline layout. This is not - * used by the BoxView itself, but by subclasses that wish to perform - * a baseline layout, like the FlowView's rows. - * - * @param axis the axis that is examined - * @param sr the <code>SizeRequirements</code> object to hold the result, - * if <code>null</code>, a new one is created - * - * @return the size requirements for this <code>BoxView</code> along - * the specified axis - */ - protected SizeRequirements baselineRequirements(int axis, - SizeRequirements sr) - { - // Create new instance if sr == null. - if (sr == null) - sr = new SizeRequirements(); - sr.alignment = 0.5F; - - // Calculate overall ascent and descent. - int totalAscentMin = 0; - int totalAscentPref = 0; - int totalAscentMax = 0; - int totalDescentMin = 0; - int totalDescentPref = 0; - int totalDescentMax = 0; - - int count = getViewCount(); - for (int i = 0; i < count; i++) - { - View v = getView(i); - float align = v.getAlignment(axis); - int span = (int) v.getPreferredSpan(axis); - int ascent = (int) (align * span); - int descent = span - ascent; - - totalAscentPref = Math.max(ascent, totalAscentPref); - totalDescentPref = Math.max(descent, totalDescentPref); - if (v.getResizeWeight(axis) > 0) - { - // If the view is resizable, then use the min and max size - // of the view. - span = (int) v.getMinimumSpan(axis); - ascent = (int) (align * span); - descent = span - ascent; - totalAscentMin = Math.max(ascent, totalAscentMin); - totalDescentMin = Math.max(descent, totalDescentMin); - - span = (int) v.getMaximumSpan(axis); - ascent = (int) (align * span); - descent = span - ascent; - totalAscentMax = Math.max(ascent, totalAscentMax); - totalDescentMax = Math.max(descent, totalDescentMax); - } - else - { - // If the view is not resizable, use the preferred span. - totalAscentMin = Math.max(ascent, totalAscentMin); - totalDescentMin = Math.max(descent, totalDescentMin); - totalAscentMax = Math.max(ascent, totalAscentMax); - totalDescentMax = Math.max(descent, totalDescentMax); - } - } - - // Preferred overall span is the sum of the preferred ascent and descent. - // With overflow check. - sr.preferred = (int) Math.min((long) totalAscentPref - + (long) totalDescentPref, - Integer.MAX_VALUE); - - // Align along the baseline. - if (sr.preferred > 0) - sr.alignment = (float) totalAscentPref / sr.preferred; - - if (sr.alignment == 0) - { - // Nothing above the baseline, use the descent. - sr.minimum = totalDescentMin; - sr.maximum = totalDescentMax; - } - else if (sr.alignment == 1.0F) - { - // Nothing below the baseline, use the descent. - sr.minimum = totalAscentMin; - sr.maximum = totalAscentMax; - } - else - { - sr.minimum = Math.max((int) (totalAscentMin / sr.alignment), - (int) (totalDescentMin / (1.0F - sr.alignment))); - sr.maximum = Math.min((int) (totalAscentMax / sr.alignment), - (int) (totalDescentMax / (1.0F - sr.alignment))); - } - return sr; - } - - /** - * Calculates the baseline layout of the children of this - * <code>BoxView</code> along the specified axis. - * - * This is not used by the BoxView itself, but by subclasses that wish to - * perform a baseline layout, like the FlowView's rows. - * - * @param span the target span - * @param axis the axis that is examined - * @param offsets an empty array, filled with the offsets of the children - * @param spans an empty array, filled with the spans of the children - */ - protected void baselineLayout(int span, int axis, int[] offsets, - int[] spans) - { - int totalAscent = (int) (span * getAlignment(axis)); - int totalDescent = span - totalAscent; - - int count = getViewCount(); - for (int i = 0; i < count; i++) - { - View v = getView(i); - float align = v.getAlignment(axis); - int viewSpan; - if (v.getResizeWeight(axis) > 0) - { - // If possible, then resize for best fit. - int min = (int) v.getMinimumSpan(axis); - int max = (int) v.getMaximumSpan(axis); - if (align == 0.0F) - viewSpan = Math.max(Math.min(max, totalDescent), min); - else if (align == 1.0F) - viewSpan = Math.max(Math.min(max, totalAscent), min); - else - { - int fit = (int) Math.min(totalAscent / align, - totalDescent / (1.0F - align)); - viewSpan = Math.max(Math.min(max, fit), min); - } - } - else - viewSpan = (int) v.getPreferredSpan(axis); - offsets[i] = totalAscent - (int) (viewSpan * align); - spans[i] = viewSpan; - } - } - - /** - * Calculates the size requirements of this <code>BoxView</code> along - * its major axis, that is the axis specified in the constructor. - * - * @param axis the axis that is examined - * @param sr the <code>SizeRequirements</code> object to hold the result, - * if <code>null</code>, a new one is created - * - * @return the size requirements for this <code>BoxView</code> along - * the specified axis - */ - protected SizeRequirements calculateMajorAxisRequirements(int axis, - SizeRequirements sr) - { - SizeRequirements res = sr; - if (res == null) - res = new SizeRequirements(); - - float min = 0; - float pref = 0; - float max = 0; - - int n = getViewCount(); - for (int i = 0; i < n; i++) - { - View child = getView(i); - min += child.getMinimumSpan(axis); - pref += child.getPreferredSpan(axis); - max += child.getMaximumSpan(axis); - } - - res.minimum = (int) min; - res.preferred = (int) pref; - res.maximum = (int) max; - res.alignment = 0.5F; - - return res; - } - - /** - * Calculates the size requirements of this <code>BoxView</code> along - * its minor axis, that is the axis opposite to the axis specified in the - * constructor. - * - * @param axis the axis that is examined - * @param sr the <code>SizeRequirements</code> object to hold the result, - * if <code>null</code>, a new one is created - * - * @return the size requirements for this <code>BoxView</code> along - * the specified axis - */ - protected SizeRequirements calculateMinorAxisRequirements(int axis, - SizeRequirements sr) - { - SizeRequirements res = sr; - if (res == null) - res = new SizeRequirements(); - - res.minimum = 0; - res.preferred = 0; - res.maximum = Integer.MAX_VALUE; - res.alignment = 0.5F; - int n = getViewCount(); - for (int i = 0; i < n; i++) - { - View child = getView(i); - res.minimum = Math.max((int) child.getMinimumSpan(axis), res.minimum); - res.preferred = Math.max((int) child.getPreferredSpan(axis), - res.preferred); - res.maximum = Math.max((int) child.getMaximumSpan(axis), res.maximum); - } - - return res; - } - - - /** - * Returns <code>true</code> if the specified point lies before the - * given <code>Rectangle</code>, <code>false</code> otherwise. - * - * "Before" is typically defined as being to the left or above. - * - * @param x the X coordinate of the point - * @param y the Y coordinate of the point - * @param r the rectangle to test the point against - * - * @return <code>true</code> if the specified point lies before the - * given <code>Rectangle</code>, <code>false</code> otherwise - */ - protected boolean isBefore(int x, int y, Rectangle r) - { - boolean result = false; - - if (myAxis == X_AXIS) - result = x < r.x; - else - result = y < r.y; - - return result; - } - - /** - * Returns <code>true</code> if the specified point lies after the - * given <code>Rectangle</code>, <code>false</code> otherwise. - * - * "After" is typically defined as being to the right or below. - * - * @param x the X coordinate of the point - * @param y the Y coordinate of the point - * @param r the rectangle to test the point against - * - * @return <code>true</code> if the specified point lies after the - * given <code>Rectangle</code>, <code>false</code> otherwise - */ - protected boolean isAfter(int x, int y, Rectangle r) - { - boolean result = false; - - if (myAxis == X_AXIS) - result = x > r.x + r.width; - else - result = y > r.y + r.height; - - return result; - } - - /** - * Returns the child <code>View</code> at the specified location. - * - * @param x the X coordinate - * @param y the Y coordinate - * @param r the inner allocation of this <code>BoxView</code> on entry, - * the allocation of the found child on exit - * - * @return the child <code>View</code> at the specified location - */ - protected View getViewAtPoint(int x, int y, Rectangle r) - { - View result = null; - int count = getViewCount(); - if (myAxis == X_AXIS) - { - // Border case. Requested point is left from the box. - if (x < r.x + offsets[X_AXIS][0]) - { - childAllocation(0, r); - result = getView(0); - } - else - { - // Search views inside box. - for (int i = 0; i < count && result == null; i++) - { - if (x < r.x + offsets[X_AXIS][i]) - { - childAllocation(i - 1, r); - result = getView(i - 1); - } - } - } - } - else // Same algorithm for Y_AXIS. - { - // Border case. Requested point is above the box. - if (y < r.y + offsets[Y_AXIS][0]) - { - childAllocation(0, r); - result = getView(0); - } - else - { - // Search views inside box. - for (int i = 0; i < count && result == null; i++) - { - if (y < r.y + offsets[Y_AXIS][i]) - { - childAllocation(i - 1, r); - result = getView(i - 1); - } - } - } - } - // Not found, other border case: point is right from or below the box. - if (result == null) - { - childAllocation(count - 1, r); - result = getView(count - 1); - } - return result; - } - - /** - * Computes the allocation for a child <code>View</code>. The parameter - * <code>a</code> stores the allocation of this <code>CompositeView</code> - * and is then adjusted to hold the allocation of the child view. - * - * @param index - * the index of the child <code>View</code> - * @param a - * the allocation of this <code>CompositeView</code> before the - * call, the allocation of the child on exit - */ - protected void childAllocation(int index, Rectangle a) - { - a.x += offsets[X_AXIS][index]; - a.y += offsets[Y_AXIS][index]; - a.width = spans[X_AXIS][index]; - a.height = spans[Y_AXIS][index]; - } - - /** - * Lays out the children of this <code>BoxView</code> with the specified - * bounds. - * - * @param width the width of the allocated region for the children (that - * is the inner allocation of this <code>BoxView</code> - * @param height the height of the allocated region for the children (that - * is the inner allocation of this <code>BoxView</code> - */ - protected void layout(int width, int height) - { - layoutAxis(X_AXIS, width); - layoutAxis(Y_AXIS, height); - } - - private void layoutAxis(int axis, int s) - { - if (span[axis] != s) - layoutValid[axis] = false; - if (! layoutValid[axis]) - { - span[axis] = s; - updateRequirements(axis); - if (axis == myAxis) - layoutMajorAxis(span[axis], axis, offsets[axis], spans[axis]); - else - layoutMinorAxis(span[axis], axis, offsets[axis], spans[axis]); - layoutValid[axis] = true; - - // Push out child layout. - int viewCount = getViewCount(); - for (int i = 0; i < viewCount; i++) - { - View v = getView(i); - v.setSize(spans[X_AXIS][i], spans[Y_AXIS][i]); - } - } - } - - /** - * Performs the layout along the major axis of a <code>BoxView</code>. - * - * @param targetSpan the (inner) span of the <code>BoxView</code> in which - * to layout the children - * @param axis the axis along which the layout is performed - * @param offsets the array that holds the offsets of the children on exit - * @param spans the array that holds the spans of the children on exit - */ - protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, - int[] spans) - { - // Set the spans to the preferred sizes. Determine the space - // that we have to adjust the sizes afterwards. - long sumPref = 0; - int n = getViewCount(); - for (int i = 0; i < n; i++) - { - View child = getView(i); - spans[i] = (int) child.getPreferredSpan(axis); - sumPref += spans[i]; - } - - // Try to adjust the spans so that we fill the targetSpan. - long diff = targetSpan - sumPref; - float factor = 0.0F; - int[] diffs = null; - if (diff != 0) - { - long total = 0; - diffs = new int[n]; - for (int i = 0; i < n; i++) - { - View child = getView(i); - int span; - if (diff < 0) - { - span = (int) child.getMinimumSpan(axis); - diffs[i] = spans[i] - span; - } - else - { - span = (int) child.getMaximumSpan(axis); - diffs[i] = span - spans[i]; - } - total += span; - } - - float maxAdjust = Math.abs(total - sumPref); - factor = diff / maxAdjust; - factor = Math.min(factor, 1.0F); - factor = Math.max(factor, -1.0F); - } - - // Actually perform adjustments. - int totalOffs = 0; - for (int i = 0; i < n; i++) - { - offsets[i] = totalOffs; - if (diff != 0) - { - float adjust = factor * diffs[i]; - spans[i] += Math.round(adjust); - } - // Avoid overflow here. - totalOffs = (int) Math.min((long) totalOffs + (long) spans[i], - Integer.MAX_VALUE); - } - } - - /** - * Performs the layout along the minor axis of a <code>BoxView</code>. - * - * @param targetSpan the (inner) span of the <code>BoxView</code> in which - * to layout the children - * @param axis the axis along which the layout is performed - * @param offsets the array that holds the offsets of the children on exit - * @param spans the array that holds the spans of the children on exit - */ - protected void layoutMinorAxis(int targetSpan, int axis, int[] offsets, - int[] spans) - { - int count = getViewCount(); - for (int i = 0; i < count; i++) - { - View child = getView(i); - int max = (int) child.getMaximumSpan(axis); - if (max < targetSpan) - { - // Align child when it can't be made as wide as the target span. - float align = child.getAlignment(axis); - offsets[i] = (int) ((targetSpan - max) * align); - spans[i] = max; - } - else - { - // Expand child to target width if possible. - int min = (int) child.getMinimumSpan(axis); - offsets[i] = 0; - spans[i] = Math.max(min, targetSpan); - } - } - } - - /** - * Returns <code>true</code> if the cached allocations for the children - * are still valid, <code>false</code> otherwise. - * - * @return <code>true</code> if the cached allocations for the children - * are still valid, <code>false</code> otherwise - */ - protected boolean isAllocationValid() - { - return isLayoutValid(X_AXIS) && isLayoutValid(Y_AXIS); - } - - /** - * Return the current width of the box. This is the last allocated width. - * - * @return the current width of the box - */ - public int getWidth() - { - // The RI returns the following here, however, I'd think that is a bug. - // return span[X_AXIS] + getLeftInset() - getRightInset(); - return span[X_AXIS] + getLeftInset() + getRightInset(); - } - - /** - * Return the current height of the box. This is the last allocated height. - * - * @return the current height of the box - */ - public int getHeight() - { - // The RI returns the following here, however, I'd think that is a bug. - // return span[Y_AXIS] + getTopInset() - getBottomInset(); - return span[Y_AXIS] + getTopInset() + getBottomInset(); - } - - /** - * Sets the size of the view. If the actual size has changed, the layout - * is updated accordingly. - * - * @param width the new width - * @param height the new height - */ - public void setSize(float width, float height) - { - layout((int) (width - getLeftInset() - getRightInset()), - (int) (height - getTopInset() - getBottomInset())); - } - - /** - * Returns the span for the child view with the given index for the specified - * axis. - * - * @param axis the axis to examine, either <code>X_AXIS</code> or - * <code>Y_AXIS</code> - * @param childIndex the index of the child for for which to return the span - * - * @return the span for the child view with the given index for the specified - * axis - */ - protected int getSpan(int axis, int childIndex) - { - if (axis != X_AXIS && axis != Y_AXIS) - throw new IllegalArgumentException("Illegal axis argument"); - return spans[axis][childIndex]; - } - - /** - * Returns the offset for the child view with the given index for the - * specified axis. - * - * @param axis the axis to examine, either <code>X_AXIS</code> or - * <code>Y_AXIS</code> - * @param childIndex the index of the child for for which to return the span - * - * @return the offset for the child view with the given index for the - * specified axis - */ - protected int getOffset(int axis, int childIndex) - { - if (axis != X_AXIS && axis != Y_AXIS) - throw new IllegalArgumentException("Illegal axis argument"); - return offsets[axis][childIndex]; - } - - /** - * Returns the alignment for this box view for the specified axis. The - * axis that is tiled (the major axis) will be requested to be aligned - * centered (0.5F). The minor axis alignment depends on the child view's - * total alignment. - * - * @param axis the axis which is examined - * - * @return the alignment for this box view for the specified axis - */ - public float getAlignment(int axis) - { - updateRequirements(axis); - return requirements[axis].alignment; - } - - /** - * Called by a child View when its preferred span has changed. - * - * @param width indicates that the preferred width of the child changed. - * @param height indicates that the preferred height of the child changed. - * @param child the child View. - */ - public void preferenceChanged(View child, boolean width, boolean height) - { - if (width) - { - layoutValid[X_AXIS] = false; - requirementsValid[X_AXIS] = false; - } - if (height) - { - layoutValid[Y_AXIS] = false; - requirementsValid[Y_AXIS] = false; - } - super.preferenceChanged(child, width, height); - } - - /** - * Maps the document model position <code>pos</code> to a Shape - * in the view coordinate space. This method overrides CompositeView's - * method to make sure the children are allocated properly before - * calling the super's behaviour. - */ - public Shape modelToView(int pos, Shape a, Position.Bias bias) - throws BadLocationException - { - // Make sure everything is allocated properly and then call super - if (! isAllocationValid()) - { - Rectangle bounds = a.getBounds(); - setSize(bounds.width, bounds.height); - } - return super.modelToView(pos, a, bias); - } - - /** - * Returns the resize weight of this view. A value of <code>0</code> or less - * means this view is not resizeable. Positive values make the view - * resizeable. This implementation returns <code>0</code> for the major - * axis and <code>1</code> for the minor axis of this box view. - * - * @param axis the axis - * - * @return the resizability of this view along the specified axis - * - * @throws IllegalArgumentException if <code>axis</code> is invalid - */ - public int getResizeWeight(int axis) - { - if (axis != X_AXIS && axis != Y_AXIS) - throw new IllegalArgumentException("Illegal axis argument"); - updateRequirements(axis); - int weight = 0; - if ((requirements[axis].preferred != requirements[axis].minimum) - || (requirements[axis].preferred != requirements[axis].maximum)) - weight = 1; - return weight; - } - - /** - * Returns the child allocation for the child view with the specified - * <code>index</code>. If the layout is invalid, this returns - * <code>null</code>. - * - * @param index the child view index - * @param a the allocation to this view - * - * @return the child allocation for the child view with the specified - * <code>index</code> or <code>null</code> if the layout is invalid - * or <code>a</code> is null - */ - public Shape getChildAllocation(int index, Shape a) - { - Shape ret = null; - if (isAllocationValid() && a != null) - ret = super.getChildAllocation(index, a); - return ret; - } - - protected void forwardUpdate(DocumentEvent.ElementChange ec, DocumentEvent e, - Shape a, ViewFactory vf) - { - boolean wasValid = isLayoutValid(myAxis); - super.forwardUpdate(ec, e, a, vf); - // Trigger repaint when one of the children changed the major axis. - if (wasValid && ! isLayoutValid(myAxis)) - { - Container c = getContainer(); - if (a != null && c != null) - { - int pos = e.getOffset(); - int index = getViewIndexAtPosition(pos); - Rectangle r = getInsideAllocation(a); - if (myAxis == X_AXIS) - { - r.x += offsets[myAxis][index]; - r.width -= offsets[myAxis][index]; - } - else - { - r.y += offsets[myAxis][index]; - r.height -= offsets[myAxis][index]; - } - c.repaint(r.x, r.y, r.width, r.height); - } - } - } - - public int viewToModel(float x, float y, Shape a, Position.Bias[] bias) - { - if (! isAllocationValid()) - { - Rectangle r = a instanceof Rectangle ? (Rectangle) a : a.getBounds(); - setSize(r.width, r.height); - } - return super.viewToModel(x, y, a, bias); - } - - protected boolean flipEastAndWestAtEnds(int position, Position.Bias bias) - { - // FIXME: What to do here? - return super.flipEastAndWestAtEnds(position, bias); - } - - /** - * Updates the view's cached requirements along the specified axis if - * necessary. The requirements are only updated if the layout for the - * specified axis is marked as invalid. - * - * @param axis the axis - */ - private void updateRequirements(int axis) - { - if (axis != Y_AXIS && axis != X_AXIS) - throw new IllegalArgumentException("Illegal axis: " + axis); - if (! requirementsValid[axis]) - { - if (axis == myAxis) - requirements[axis] = calculateMajorAxisRequirements(axis, - requirements[axis]); - else - requirements[axis] = calculateMinorAxisRequirements(axis, - requirements[axis]); - requirementsValid[axis] = true; - } - } -} |