asyncboxview.java
来自「linux下建立JAVA虚拟机的源码KAFFE」· Java 代码 · 共 1,481 行 · 第 1/3 页
JAVA
1,481 行
* and locked the document. */ private void update() { int majorAxis = getMajorAxis(); boolean minorUpdated = false; synchronized (this) { if (! minorValid) { int minorAxis = getMinorAxis(); minimum = childView.getMinimumSpan(minorAxis); preferred = childView.getPreferredSpan(minorAxis); maximum = childView.getMaximumSpan(minorAxis); minorValid = true; minorUpdated = true; } } if (minorUpdated) minorRequirementChange(this); boolean majorUpdated = false; float delta = 0.0F; synchronized (this) { if (! majorValid) { float oldSpan = majorSpan; majorSpan = childView.getPreferredSpan(majorAxis); delta = majorSpan - oldSpan; majorValid = true; majorUpdated = true; } } if (majorUpdated) { majorRequirementChange(this, delta); locator.childChanged(this); } synchronized (this) { if (! childSizeValid) { float w; float h; if (majorAxis == X_AXIS) { w = majorSpan; h = getMinorSpan(); } else { w = getMinorSpan(); h = majorSpan; } childSizeValid = true; childView.setSize(w, h); } } } /** * Returns the span of the child view along the minor layout axis. * * @return the span of the child view along the minor layout axis */ public float getMinorSpan() { float retVal; if (maximum < minorSpan) retVal = maximum; else retVal = Math.max(minimum, minorSpan); return retVal; } /** * Returns the offset of the child view along the minor layout axis. * * @return the offset of the child view along the minor layout axis */ public float getMinorOffset() { float retVal; if (maximum < minorSpan) { float align = childView.getAlignment(getMinorAxis()); retVal = ((minorSpan - maximum) * align); } else retVal = 0f; return retVal; } /** * Returns the span of the child view along the major layout axis. * * @return the span of the child view along the major layout axis */ public float getMajorSpan() { return majorSpan; } /** * Returns the offset of the child view along the major layout axis. * * @return the offset of the child view along the major layout axis */ public float getMajorOffset() { return majorOffset; } /** * Sets the offset of the child view along the major layout axis. This * should only be called by the ChildLocator of that child view. * * @param offset the offset to set */ public void setMajorOffset(float offset) { majorOffset = offset; } /** * Mark the preferences changed for that child. This forwards to * {@link AsyncBoxView#preferenceChanged}. * * @param width <code>true</code> if the width preference has changed * @param height <code>true</code> if the height preference has changed */ public void preferenceChanged(boolean width, boolean height) { if (getMajorAxis() == X_AXIS) { if (width) majorValid = false; if (height) minorValid = false; } else { if (width) minorValid = false; if (height) majorValid = false; } childSizeValid = false; } } /** * Flushes the requirements changes upwards asynchronously. */ private class FlushTask implements Runnable { /** * Starts the flush task. This obtains a readLock on the document * and then flushes all the updates using * {@link AsyncBoxView#flushRequirementChanges()} after updating the * requirements. */ public void run() { try { // Acquire a lock on the document. Document doc = getDocument(); if (doc instanceof AbstractDocument) { AbstractDocument abstractDoc = (AbstractDocument) doc; abstractDoc.readLock(); } int n = getViewCount(); if (minorChanged && (n > 0)) { LayoutQueue q = getLayoutQueue(); ChildState min = getChildState(0); ChildState pref = getChildState(0); for (int i = 1; i < n; i++) { ChildState cs = getChildState(i); if (cs.minimum > min.minimum) min = cs; if (cs.preferred > pref.preferred) pref = cs; } synchronized (AsyncBoxView.this) { minReq = min; prefReq = pref; } } flushRequirementChanges(); } finally { // Release the lock on the document. Document doc = getDocument(); if (doc instanceof AbstractDocument) { AbstractDocument abstractDoc = (AbstractDocument) doc; abstractDoc.readUnlock(); } } } } /** * The major layout axis. */ private int majorAxis; /** * The top inset. */ private float topInset; /** * The bottom inset. */ private float bottomInset; /** * The left inset. */ private float leftInset; /** * Indicates if the major span should be treated as beeing estimated or not. */ private boolean estimatedMajorSpan; /** * The right inset. */ private float rightInset; /** * The children and their layout statistics. */ private ArrayList childStates; /** * The currently changing child state. May be null if there is no child state * updating at the moment. This is package private to avoid a synthetic * accessor method inside ChildState. */ ChildState changing; /** * Represents the minimum requirements. This is used in * {@link #getMinimumSpan(int)}. */ ChildState minReq; /** * Represents the minimum requirements. This is used in * {@link #getPreferredSpan(int)}. */ ChildState prefReq; /** * Indicates that the major axis requirements have changed. */ private boolean majorChanged; /** * Indicates that the minor axis requirements have changed. This is package * private to avoid synthetic accessor method. */ boolean minorChanged; /** * The current span along the major layout axis. This is package private to * avoid synthetic accessor method. */ float majorSpan; /** * The current span along the minor layout axis. This is package private to * avoid synthetic accessor method. */ float minorSpan; /** * This tasked is placed on the layout queue to flush updates up to the * parent view. */ private Runnable flushTask; /** * The child locator for this view. */ protected ChildLocator locator; /** * Creates a new <code>AsyncBoxView</code> that represents the specified * element and layouts its children along the specified axis. * * @param elem the element * @param axis the layout axis */ public AsyncBoxView(Element elem, int axis) { super(elem); majorAxis = axis; childStates = new ArrayList(); flushTask = new FlushTask(); locator = new ChildLocator(); minorSpan = Short.MAX_VALUE; } /** * Returns the major layout axis. * * @return the major layout axis */ public int getMajorAxis() { return majorAxis; } /** * Returns the minor layout axis, that is the axis orthogonal to the major * layout axis. * * @return the minor layout axis */ public int getMinorAxis() { return majorAxis == X_AXIS ? Y_AXIS : X_AXIS; } /** * Returns the view at the specified <code>index</code>. * * @param index the index of the requested child view * * @return the view at the specified <code>index</code> */ public View getView(int index) { View view = null; synchronized(childStates) { if ((index >= 0) && (index < childStates.size())) { ChildState cs = (ChildState) childStates.get(index); view = cs.getChildView(); } } return view; } /** * Returns the number of child views. * * @return the number of child views */ public int getViewCount() { synchronized(childStates) { return childStates.size(); } } /** * Returns the view index of the child view that represents the specified * model position. * * @param pos the model position for which we search the view index * @param bias the bias * * @return the view index of the child view that represents the specified * model position */ public int getViewIndex(int pos, Position.Bias bias) { int retVal = -1; if (bias == Position.Bias.Backward) pos = Math.max(0, pos - 1); // TODO: A possible optimization would be to implement a binary search // here. int numChildren = childStates.size(); if (numChildren > 0) { for (int i = 0; i < numChildren; ++i) { View child = ((ChildState) childStates.get(i)).getChildView(); if (child.getStartOffset() <= pos && child.getEndOffset() > pos) { retVal = i; break; } } } return retVal; } /** * Returns the top inset. * * @return the top inset */ public float getTopInset() { return topInset; } /** * Sets the top inset. * * @param top the top inset */ public void setTopInset(float top) { topInset = top; } /** * Returns the bottom inset. * * @return the bottom inset */ public float getBottomInset() { return bottomInset; } /** * Sets the bottom inset. * * @param bottom the bottom inset */ public void setBottomInset(float bottom) { bottomInset = bottom; } /** * Returns the left inset. * * @return the left inset */ public float getLeftInset() { return leftInset; } /** * Sets the left inset. * * @param left the left inset */ public void setLeftInset(float left) { leftInset = left; } /** * Returns the right inset. * * @return the right inset */ public float getRightInset() { return rightInset; } /** * Sets the right inset. * * @param right the right inset */ public void setRightInset(float right) { rightInset = right; } /** * Loads the child views of this view. This is triggered by * {@link #setParent(View)}. *
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?