Package javax.swing.text.html

Source Code of javax.swing.text.html.BlockView

/*
* @(#)BlockView.java  1.38 06/02/14
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package javax.swing.text.html;

import java.util.Enumeration;
import java.awt.*;
import javax.swing.SizeRequirements;
import javax.swing.border.*;
import javax.swing.event.DocumentEvent;
import javax.swing.text.*;

/**
* A view implementation to display a block (as a box)
* with CSS specifications.
*
* @author  Timothy Prinzing
* @version 1.38 02/14/06
*/
public class BlockView extends BoxView  {

    /**
     * Creates a new view that represents an
     * html box.  This can be used for a number
     * of elements.
     *
     * @param elem the element to create a view for
     * @param axis either View.X_AXIS or View.Y_AXIS
     */
    public BlockView(Element elem, int axis) {
  super(elem, axis);
    }

    /**
     * Establishes the parent view for this view.  This is
     * guaranteed to be called before any other methods if the
     * parent view is functioning properly.
     * <p>
     * This is implemented
     * to forward to the superclass as well as call the
     * {@link #setPropertiesFromAttributes()}
     * method to set the paragraph properties from the css
     * attributes.  The call is made at this time to ensure
     * the ability to resolve upward through the parents
     * view attributes.
     *
     * @param parent the new parent, or null if the view is
     *  being removed from a parent it was previously added
     *  to
     */
    public void setParent(View parent) {
  super.setParent(parent);
        if (parent != null) {
            setPropertiesFromAttributes();
        }
    }

    /**
     * Calculate the requirements of the block along the major
     * axis (i.e. the axis along with it tiles).  This is implemented
     * to provide the superclass behavior and then adjust it if the
     * CSS width or height attribute is specified and applicable to
     * the axis.
     */
    protected SizeRequirements calculateMajorAxisRequirements(int axis, SizeRequirements r) {
  if (r == null) {
      r = new SizeRequirements();
  }
  if (! spanSetFromAttributes(axis, r, cssWidth, cssHeight)) {
      r = super.calculateMajorAxisRequirements(axis, r);
  }
        else {
            // Offset by the margins so that pref/min/max return the
            // right value.
            SizeRequirements parentR = super.calculateMajorAxisRequirements(
                                      axis, null);
            int margin = (axis == X_AXIS) ? getLeftInset() + getRightInset() :
                                            getTopInset() + getBottomInset();
            r.minimum -= margin;
            r.preferred -= margin;
            r.maximum -= margin;
            constrainSize(axis, r, parentR);
        }
  return r;
    }

    /**
     * Calculate the requirements of the block along the minor
     * axis (i.e. the axis orthoginal to the axis along with it tiles). 
     * This is implemented
     * to provide the superclass behavior and then adjust it if the
     * CSS width or height attribute is specified and applicable to
     * the axis.
     */
    protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
  if (r == null) {
      r = new SizeRequirements();
  }

  if (! spanSetFromAttributes(axis, r, cssWidth, cssHeight)) {

      /*
       * The requirements were not directly specified by attributes, so
       * compute the aggregate of the requirements of the children.  The
       * children that have a percentage value specified will be treated
       * as completely stretchable since that child is not limited in any
       * way.
       */
/*
      int min = 0;
      long pref = 0;
      int max = 0;
      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);
    if (
    max = Math.max((int) v.getMaximumSpan(axis), max);

      }
      r.preferred = (int) pref;
      r.minimum = min;
      r.maximum = max;
      */
      r = super.calculateMinorAxisRequirements(axis, r);
  }
        else {
            // Offset by the margins so that pref/min/max return the
            // right value.
            SizeRequirements parentR = super.calculateMinorAxisRequirements(
                                      axis, null);
            int margin = (axis == X_AXIS) ? getLeftInset() + getRightInset() :
                                            getTopInset() + getBottomInset();
            r.minimum -= margin;
            r.preferred -= margin;
            r.maximum -= margin;
            constrainSize(axis, r, parentR);
        }

  /*
   * Set the alignment based upon the CSS properties if it is
   * specified.  For X_AXIS this would be text-align, for
   * Y_AXIS this would be vertical-align.
   */
  if (axis == X_AXIS) {
      Object o = getAttributes().getAttribute(CSS.Attribute.TEXT_ALIGN);
      if (o != null) {
    String align = o.toString();
    if (align.equals("center")) {
        r.alignment = 0.5f;
    } else if (align.equals("right")) {
        r.alignment = 1.0f;
    } else {
        r.alignment = 0.0f;
    }
      }
  }
  // Y_AXIS TBD
  return r;
    }

    boolean isPercentage(int axis, AttributeSet a) {
  if (axis == X_AXIS) {
      if (cssWidth != null) {
    return cssWidth.isPercentage();
      }
  } else {
      if (cssHeight != null) {
    return cssHeight.isPercentage();
      }
  }
  return false;
    }
     
    /**
     * Adjust the given requirements to the CSS width or height if
     * it is specified along the applicable axis.  Return true if the
     * size is exactly specified, false if the span is not specified
     * in an attribute or the size specified is a percentage.
     */
    static boolean spanSetFromAttributes(int axis, SizeRequirements r,
                                         CSS.LengthValue cssWidth,
                                         CSS.LengthValue cssHeight) {
  if (axis == X_AXIS) {
      if ((cssWidth != null) && (! cssWidth.isPercentage())) {
    r.minimum = r.preferred = r.maximum = (int) cssWidth.getValue();
    return true;
      }
  } else {
      if ((cssHeight != null) && (! cssHeight.isPercentage())) {
    r.minimum = r.preferred = r.maximum = (int) cssHeight.getValue();
    return true;
      }
  }
  return false;
    }

    /**
     * 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
     *  whould be used to layout the childre.
     * @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();
  Object key = (axis == X_AXIS) ? CSS.Attribute.WIDTH : CSS.Attribute.HEIGHT;
  for (int i = 0; i < n; i++) {
      View v = getView(i);
      int min = (int) v.getMinimumSpan(axis);
      int max;

      // check for percentage span
      AttributeSet a = v.getAttributes();
      CSS.LengthValue lv = (CSS.LengthValue) a.getAttribute(key);
      if ((lv != null) && lv.isPercentage()) {
    // bound the span to the percentage specified
    min = Math.max((int) lv.getValue(targetSpan), min);
    max = min;
      } else {
                max = (int)v.getMaximumSpan(axis);
      }

      // assign the offset and span for the child
      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.
    offsets[i] = 0;
    spans[i] = Math.max(min, targetSpan);
      }
  }
    }


    /**
     * Renders using the given rendering surface and area on that
     * surface.  This is implemented to delegate to the css box
     * painter to paint the border and background prior to the
     * interior.
     *
     * @param g the rendering surface to use
     * @param allocation the allocated region to render into
     * @see View#paint
     */
    public void paint(Graphics g, Shape allocation) {
  Rectangle a = (Rectangle) allocation;
  painter.paint(g, a.x, a.y, a.width, a.height, this);
  super.paint(g, a);
    }

    /**
     * Fetches the attributes to use when rendering.  This is
     * implemented to multiplex the attributes specified in the
     * model with a StyleSheet.
     */
    public AttributeSet getAttributes() {
  if (attr == null) {
      StyleSheet sheet = getStyleSheet();
      attr = sheet.getViewAttributes(this);
  }
  return attr;
    }

    /**
     * Gets the resize weight.
     *
     * @param axis may be either X_AXIS or Y_AXIS
     * @return the weight
     * @exception IllegalArgumentException for an invalid axis
     */
    public int getResizeWeight(int axis) {
  switch (axis) {
  case View.X_AXIS:
      return 1;
  case View.Y_AXIS:
      return 0;
  default:
      throw new IllegalArgumentException("Invalid axis: " + axis);
  }
    }

    /**
     * Gets the alignment.
     *
     * @param axis may be either X_AXIS or Y_AXIS
     * @return the alignment
     */
    public float getAlignment(int axis) {
  switch (axis) {
  case View.X_AXIS:
      return 0;
  case View.Y_AXIS:
      if (getViewCount() == 0) {
    return 0;
      }
      float span = getPreferredSpan(View.Y_AXIS);
      View v = getView(0);
      float above = v.getPreferredSpan(View.Y_AXIS);
      float a = (((int)span) != 0) ? (above * v.getAlignment(View.Y_AXIS)) / span: 0;
      return a;
  default:
      throw new IllegalArgumentException("Invalid axis: " + axis);
  }
    }

    public void changedUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
  super.changedUpdate(changes, a, f);
  int pos = changes.getOffset();
  if (pos <= getStartOffset() && (pos + changes.getLength()) >=
      getEndOffset()) {
      setPropertiesFromAttributes();
  }
    }

    /**
     * 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) {
  return super.getPreferredSpan(axis);
    }

    /**
     * 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) {
  return super.getMinimumSpan(axis);
    }

    /**
     * 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) {
  return super.getMaximumSpan(axis);
    }

    /**
     * Update any cached values that come from attributes.
     */
    protected void setPropertiesFromAttributes() {

  // update attributes
  StyleSheet sheet = getStyleSheet();
  attr = sheet.getViewAttributes(this);

  // Reset the painter
  painter = sheet.getBoxPainter(attr);
  if (attr != null) {
      setInsets((short) painter.getInset(TOP, this),
          (short) painter.getInset(LEFT, this),
          (short) painter.getInset(BOTTOM, this),
          (short) painter.getInset(RIGHT, this));
  }

  // Get the width/height
  cssWidth = (CSS.LengthValue) attr.getAttribute(CSS.Attribute.WIDTH);
  cssHeight = (CSS.LengthValue) attr.getAttribute(CSS.Attribute.HEIGHT);
    }

    protected StyleSheet getStyleSheet() {
  HTMLDocument doc = (HTMLDocument) getDocument();
  return doc.getStyleSheet();
    }

    /**
     * Constrains <code>want</code> to fit in the minimum size specified
     * by <code>min</code>.
     */
    private void constrainSize(int axis, SizeRequirements want,
                               SizeRequirements min) {
        if (min.minimum > want.minimum) {
            want.minimum = want.preferred = min.minimum;
            want.maximum = Math.max(want.maximum, min.maximum);
        }
    }

    private AttributeSet attr;
    private StyleSheet.BoxPainter painter;

    private CSS.LengthValue cssWidth;
    private CSS.LengthValue cssHeight;

}
TOP

Related Classes of javax.swing.text.html.BlockView

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.