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 + -
显示快捷键?