1. /*
  2. * @(#)ParagraphView.java 1.21 00/02/02
  3. *
  4. * Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing.text.html;
  11. import java.awt.*;
  12. import javax.swing.SizeRequirements;
  13. import javax.swing.event.DocumentEvent;
  14. import javax.swing.text.Document;
  15. import javax.swing.text.Element;
  16. import javax.swing.text.AttributeSet;
  17. import javax.swing.text.StyleConstants;
  18. import javax.swing.text.View;
  19. import javax.swing.text.ViewFactory;
  20. import javax.swing.text.BadLocationException;
  21. import javax.swing.text.JTextComponent;
  22. /**
  23. * Displays the a paragraph, and uses css attributes for its
  24. * configuration.
  25. *
  26. * @author Timothy Prinzing
  27. * @version 1.21 02/02/00
  28. */
  29. public class ParagraphView extends javax.swing.text.ParagraphView {
  30. /**
  31. * Constructs a ParagraphView for the given element.
  32. *
  33. * @param elem the element that this view is responsible for
  34. */
  35. public ParagraphView(Element elem) {
  36. super(elem);
  37. }
  38. /**
  39. * Establishes the parent view for this view. This is
  40. * guaranteed to be called before any other methods if the
  41. * parent view is functioning properly.
  42. * <p>
  43. * This is implemented
  44. * to forward to the superclass as well as call the
  45. * <a href="#setPropertiesFromAttributes">setPropertiesFromAttributes</a>
  46. * method to set the paragraph properties from the css
  47. * attributes. The call is made at this time to ensure
  48. * the ability to resolve upward through the parents
  49. * view attributes.
  50. *
  51. * @param parent the new parent, or null if the view is
  52. * being removed from a parent it was previously added
  53. * to
  54. */
  55. public void setParent(View parent) {
  56. super.setParent(parent);
  57. setPropertiesFromAttributes();
  58. }
  59. /**
  60. * Fetches the attributes to use when rendering. This is
  61. * implemented to multiplex the attributes specified in the
  62. * model with a StyleSheet.
  63. */
  64. public AttributeSet getAttributes() {
  65. if (attr == null) {
  66. StyleSheet sheet = getStyleSheet();
  67. attr = sheet.getViewAttributes(this);
  68. }
  69. return attr;
  70. }
  71. /**
  72. * Sets up the paragraph from css attributes instead of
  73. * the values found in StyleConstants (i.e. which are used
  74. * by the superclass). Since
  75. */
  76. protected void setPropertiesFromAttributes() {
  77. StyleSheet sheet = getStyleSheet();
  78. attr = sheet.getViewAttributes(this);
  79. painter = sheet.getBoxPainter(attr);
  80. if (attr != null) {
  81. super.setPropertiesFromAttributes();
  82. setInsets((short) painter.getInset(TOP, this),
  83. (short) painter.getInset(LEFT, this),
  84. (short) painter.getInset(BOTTOM, this),
  85. (short) painter.getInset(RIGHT, this));
  86. Object o = attr.getAttribute(CSS.Attribute.TEXT_ALIGN);
  87. if (o != null) {
  88. // set horizontal alignment
  89. String ta = o.toString();
  90. if (ta.equals("left")) {
  91. setJustification(StyleConstants.ALIGN_LEFT);
  92. } else if (ta.equals("center")) {
  93. setJustification(StyleConstants.ALIGN_CENTER);
  94. } else if (ta.equals("right")) {
  95. setJustification(StyleConstants.ALIGN_RIGHT);
  96. } else if (ta.equals("justify")) {
  97. setJustification(StyleConstants.ALIGN_JUSTIFIED);
  98. }
  99. }
  100. }
  101. }
  102. protected StyleSheet getStyleSheet() {
  103. HTMLDocument doc = (HTMLDocument) getDocument();
  104. return doc.getStyleSheet();
  105. }
  106. /**
  107. * Calculate the needs for the paragraph along the minor axis.
  108. * This implemented to use the requirements of the superclass,
  109. * modified slightly to set a minimum span allowed. Typical
  110. * html rendering doesn't let the view size shrink smaller than
  111. * the length of the longest word.
  112. */
  113. protected SizeRequirements calculateMinorAxisRequirements(int axis, SizeRequirements r) {
  114. r = super.calculateMinorAxisRequirements(axis, r);
  115. // PENDING(prinz) Need to make this better so it doesn't require
  116. // InlineView and works with font changes within the word.
  117. // find the longest minimum span.
  118. float min = 0;
  119. int n = getLayoutViewCount();
  120. for (int i = 0; i < n; i++) {
  121. View v = getLayoutView(i);
  122. if (v instanceof InlineView) {
  123. float wordSpan = ((InlineView) v).getLongestWordSpan();
  124. min = Math.max(wordSpan, min);
  125. } else {
  126. min = Math.max(v.getMinimumSpan(axis), min);
  127. }
  128. }
  129. r.minimum = Math.max(r.minimum, (int) min);
  130. r.preferred = Math.max(r.minimum, r.preferred);
  131. r.maximum = Math.max(r.preferred, r.maximum);
  132. return r;
  133. }
  134. /**
  135. * Indicates whether or not this view should be
  136. * displayed. If none of the children wish to be
  137. * displayed and the only visible child is the
  138. * break that ends the paragraph, the paragraph
  139. * will not be considered visible. Otherwise,
  140. * it will be considered visible and return true.
  141. *
  142. * @returns true if the paragraph should be displayed.
  143. */
  144. public boolean isVisible() {
  145. int n = getLayoutViewCount() - 1;
  146. for (int i = 0; i < n; i++) {
  147. View v = getLayoutView(i);
  148. if (v.isVisible()) {
  149. return true;
  150. }
  151. }
  152. if (n > 0) {
  153. View v = getLayoutView(n);
  154. if ((v.getEndOffset() - v.getStartOffset()) == 1) {
  155. return false;
  156. }
  157. }
  158. // If it's the last paragraph and not editable, it shouldn't
  159. // be visible.
  160. if (getStartOffset() == getDocument().getLength()) {
  161. boolean editable = false;
  162. Component c = getContainer();
  163. if (c instanceof JTextComponent) {
  164. editable = ((JTextComponent)c).isEditable();
  165. }
  166. if (!editable) {
  167. return false;
  168. }
  169. }
  170. return true;
  171. }
  172. /**
  173. * Renders using the given rendering surface and area on that
  174. * surface. This is implemented to delgate to the superclass
  175. * after stashing the base coordinate for tab calculations.
  176. *
  177. * @param g the rendering surface to use
  178. * @param a the allocated region to render into
  179. * @see View#paint
  180. */
  181. public void paint(Graphics g, Shape a) {
  182. Rectangle r;
  183. if (a instanceof Rectangle) {
  184. r = (Rectangle) a;
  185. } else {
  186. r = a.getBounds();
  187. }
  188. painter.paint(g, r.x, r.y, r.width, r.height, this);
  189. super.paint(g, a);
  190. }
  191. /**
  192. * Determines the preferred span for this view. Returns
  193. * 0 if the view is not visible, otherwise it calls the
  194. * superclass method to get the preferred span.
  195. * axis.
  196. *
  197. * @param axis may be either View.X_AXIS or View.Y_AXIS
  198. * @returns the span the view would like to be rendered into.
  199. * Typically the view is told to render into the span
  200. * that is returned, although there is no guarantee.
  201. * The parent may choose to resize or break the view.
  202. * @see javax.swing.text.ParagraphView#getPreferredSpan
  203. */
  204. public float getPreferredSpan(int axis) {
  205. if (!isVisible()) {
  206. return 0;
  207. }
  208. return super.getPreferredSpan(axis);
  209. }
  210. /**
  211. * Determines the minimum span for this view along an
  212. * axis. Returns 0 if the view is not visible, otherwise
  213. * it calls the superclass method to get the minimum span.
  214. *
  215. * @param axis may be either View.X_AXIS or View.Y_AXIS
  216. * @returns the minimum span the view can be rendered into.
  217. * @see javax.swing.text.ParagraphView#getMinimumSpan
  218. */
  219. public float getMinimumSpan(int axis) {
  220. if (!isVisible()) {
  221. return 0;
  222. }
  223. return super.getMinimumSpan(axis);
  224. }
  225. /**
  226. * Determines the maximum span for this view along an
  227. * axis. Returns 0 if the view is not visible, otherwise
  228. * it calls the superclass method ot get the maximum span.
  229. *
  230. * @param axis may be either View.X_AXIS or View.Y_AXIS
  231. * @returns the maximum span the view can be rendered into.
  232. * @see javax.swing.text.ParagraphView#getMaximumSpan
  233. */
  234. public float getMaximumSpan(int axis) {
  235. if (!isVisible()) {
  236. return 0;
  237. }
  238. return super.getMaximumSpan(axis);
  239. }
  240. private AttributeSet attr;
  241. private StyleSheet.BoxPainter painter;
  242. }