1. /*
  2. * @(#)BlockView.java 1.18 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.text.html;
  8. import java.util.Enumeration;
  9. import java.awt.*;
  10. import javax.swing.SizeRequirements;
  11. import javax.swing.border.*;
  12. import javax.swing.event.DocumentEvent;
  13. import javax.swing.text.*;
  14. /**
  15. * A view implementation to display a block (as a box)
  16. * with CSS specifications.
  17. *
  18. * @author Timothy Prinzing
  19. * @version 1.18 11/29/01
  20. */
  21. public class BlockView extends BoxView {
  22. /**
  23. * Creates a new view that represents an
  24. * html box. This can be used for a number
  25. * of elements.
  26. *
  27. * @param elem the element to create a view for
  28. * @param axis either View.X_AXIS or View.Y_AXIS
  29. */
  30. public BlockView(Element elem, int axis) {
  31. super(elem, axis);
  32. StyleSheet sheet = getStyleSheet();
  33. attr = sheet.getViewAttributes(this);
  34. painter = sheet.getBoxPainter(attr);
  35. setPropertiesFromAttributes();
  36. }
  37. /**
  38. * Calculate the requirements of the block along the major
  39. * axis (i.e. the axis along with it tiles). This is implemented
  40. * to provide the superclass behavior and then adjust it if the
  41. * CSS width or height attribute is specified and applicable to
  42. * the axis.
  43. */
  44. protected SizeRequirements calculateMajorAxisRequirements(int axis, SizeRequirements r) {
  45. SizeRequirements rr = super.calculateMajorAxisRequirements(axis, r);
  46. adjustSizeForCSS(axis, rr);
  47. return rr;
  48. }
  49. /**
  50. * Calculate the requirements of the block along the minor
  51. * axis (i.e. the axis orthoginal to the axis along with it tiles).
  52. * This is implemented
  53. * to provide the superclass behavior and then adjust it if the
  54. * CSS width or height attribute is specified and applicable to
  55. * the axis.
  56. */
  57. protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
  58. SizeRequirements rr = super.calculateMinorAxisRequirements(axis, r);
  59. adjustSizeForCSS(axis, rr);
  60. return rr;
  61. }
  62. /**
  63. * Adjust the given requirements to the CSS width or height if
  64. * it is specified along the applicable axis.
  65. */
  66. /*protected*/ void adjustSizeForCSS(int axis, SizeRequirements r) {
  67. if (axis == X_AXIS) {
  68. Object widthValue = attr.getAttribute(CSS.Attribute.WIDTH);
  69. if (widthValue != null) {
  70. int width = (int) ((CSS.LengthValue)widthValue).getValue();
  71. r.minimum = r.preferred = width;
  72. r.maximum = Math.max(r.maximum, width);
  73. }
  74. } else {
  75. Object heightValue = attr.getAttribute(CSS.Attribute.HEIGHT);
  76. if (heightValue != null) {
  77. int height = (int) ((CSS.LengthValue)heightValue).getValue();
  78. r.minimum = r.preferred = height;
  79. r.maximum = Math.max(r.maximum, height);
  80. }
  81. }
  82. }
  83. /**
  84. * Renders using the given rendering surface and area on that
  85. * surface. This is implemented to delegate to the css box
  86. * painter to paint the border and background prior to the
  87. * interior.
  88. *
  89. * @param g the rendering surface to use
  90. * @param allocation the allocated region to render into
  91. * @see View#paint
  92. */
  93. public void paint(Graphics g, Shape allocation) {
  94. Rectangle a = (Rectangle) allocation;
  95. painter.paint(g, a.x, a.y, a.width, a.height, this);
  96. super.paint(g, a);
  97. }
  98. /**
  99. * Fetches the attributes to use when rendering. This is
  100. * implemented to multiplex the attributes specified in the
  101. * model with a StyleSheet.
  102. */
  103. public AttributeSet getAttributes() {
  104. return attr;
  105. }
  106. /**
  107. * Gets the resize weight.
  108. *
  109. * @param axis may be either X_AXIS or Y_AXIS
  110. * @return the weight
  111. * @exception IllegalArgumentException for an invalid axis
  112. */
  113. public int getResizeWeight(int axis) {
  114. switch (axis) {
  115. case View.X_AXIS:
  116. return 1;
  117. case View.Y_AXIS:
  118. return 0;
  119. default:
  120. throw new IllegalArgumentException("Invalid axis: " + axis);
  121. }
  122. }
  123. /**
  124. * Gets the alignment.
  125. *
  126. * @param axis may be either X_AXIS or Y_AXIS
  127. * @return the alignment
  128. */
  129. public float getAlignment(int axis) {
  130. switch (axis) {
  131. case View.X_AXIS:
  132. return 0;
  133. case View.Y_AXIS:
  134. float span = getPreferredSpan(View.Y_AXIS);
  135. View v = getView(0);
  136. float above = v.getPreferredSpan(View.Y_AXIS);
  137. float a = (((int)span) != 0) ? (above * v.getAlignment(View.Y_AXIS)) / span: 0;
  138. return a;
  139. default:
  140. throw new IllegalArgumentException("Invalid axis: " + axis);
  141. }
  142. }
  143. public void changedUpdate(DocumentEvent changes, Shape a, ViewFactory f) {
  144. super.changedUpdate(changes, a, f);
  145. int pos = changes.getOffset();
  146. if (pos <= getStartOffset() && (pos + changes.getLength()) >=
  147. getEndOffset()) {
  148. setPropertiesFromAttributes();
  149. }
  150. }
  151. /**
  152. * Update any cached values that come from attributes.
  153. */
  154. protected void setPropertiesFromAttributes() {
  155. attr = getStyleSheet().getViewAttributes(this);
  156. if (attr != null) {
  157. setInsets((short) painter.getInset(TOP, this),
  158. (short) painter.getInset(LEFT, this),
  159. (short) painter.getInset(BOTTOM, this),
  160. (short) painter.getInset(RIGHT, this));
  161. }
  162. }
  163. protected StyleSheet getStyleSheet() {
  164. HTMLDocument doc = (HTMLDocument) getDocument();
  165. return doc.getStyleSheet();
  166. }
  167. private AttributeSet attr;
  168. private StyleSheet.BoxPainter painter;
  169. }