KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > text > html > InlineView


1 /*
2  * @(#)InlineView.java 1.26 06/06/30
3  *
4  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package javax.swing.text.html;
8
9 import java.awt.*;
10 import java.text.BreakIterator JavaDoc;
11 import javax.swing.event.DocumentEvent JavaDoc;
12 import javax.swing.text.*;
13
14 /**
15  * Displays the <dfn>inline element</dfn> styles
16  * based upon css attributes.
17  *
18  * @author Timothy Prinzing
19  * @version 1.26 06/30/06
20  */

21 public class InlineView extends LabelView {
22
23     /**
24      * Constructs a new view wrapped on an element.
25      *
26      * @param elem the element
27      */

28     public InlineView(Element elem) {
29     super(elem);
30     StyleSheet JavaDoc sheet = getStyleSheet();
31     attr = sheet.getViewAttributes(this);
32     }
33
34     /**
35      * Gives notification that something was inserted into
36      * the document in a location that this view is responsible for.
37      * If either parameter is <code>null</code>, behavior of this method is
38      * implementation dependent.
39      *
40      * @param e the change information from the associated document
41      * @param a the current allocation of the view
42      * @param f the factory to use to rebuild if the view has children
43      * @since 1.5
44      * @see View#insertUpdate
45      */

46     public void insertUpdate(DocumentEvent JavaDoc e, Shape a, ViewFactory f) {
47     super.insertUpdate(e, a, f);
48         longestWordSpan = -1.0f;
49     }
50
51     /**
52      * Gives notification that something was removed from the document
53      * in a location that this view is responsible for.
54      * If either parameter is <code>null</code>, behavior of this method is
55      * implementation dependent.
56      *
57      * @param e the change information from the associated document
58      * @param a the current allocation of the view
59      * @param f the factory to use to rebuild if the view has children
60      * @since 1.5
61      * @see View#removeUpdate
62      */

63     public void removeUpdate(DocumentEvent JavaDoc e, Shape a, ViewFactory f) {
64         super.removeUpdate(e, a, f);
65         longestWordSpan = -1.0f;
66     }
67
68     /**
69      * Gives notification from the document that attributes were changed
70      * in a location that this view is responsible for.
71      *
72      * @param e the change information from the associated document
73      * @param a the current allocation of the view
74      * @param f the factory to use to rebuild if the view has children
75      * @see View#changedUpdate
76      */

77     public void changedUpdate(DocumentEvent JavaDoc e, Shape a, ViewFactory f) {
78     super.changedUpdate(e, a, f);
79     StyleSheet JavaDoc sheet = getStyleSheet();
80     attr = sheet.getViewAttributes(this);
81         longestWordSpan = -1.0f;
82     preferenceChanged(null, true, true);
83     }
84
85     /**
86      * Fetches the attributes to use when rendering. This is
87      * implemented to multiplex the attributes specified in the
88      * model with a StyleSheet.
89      */

90     public AttributeSet getAttributes() {
91     return attr;
92     }
93
94     /**
95      * Determines how attractive a break opportunity in
96      * this view is. This can be used for determining which
97      * view is the most attractive to call <code>breakView</code>
98      * on in the process of formatting. A view that represents
99      * text that has whitespace in it might be more attractive
100      * than a view that has no whitespace, for example. The
101      * higher the weight, the more attractive the break. A
102      * value equal to or lower than <code>BadBreakWeight</code>
103      * should not be considered for a break. A value greater
104      * than or equal to <code>ForcedBreakWeight</code> should
105      * be broken.
106      * <p>
107      * This is implemented to provide the default behavior
108      * of returning <code>BadBreakWeight</code> unless the length
109      * is greater than the length of the view in which case the
110      * entire view represents the fragment. Unless a view has
111      * been written to support breaking behavior, it is not
112      * attractive to try and break the view. An example of
113      * a view that does support breaking is <code>LabelView</code>.
114      * An example of a view that uses break weight is
115      * <code>ParagraphView</code>.
116      *
117      * @param axis may be either View.X_AXIS or View.Y_AXIS
118      * @param pos the potential location of the start of the
119      * broken view >= 0. This may be useful for calculating tab
120      * positions.
121      * @param len specifies the relative length from <em>pos</em>
122      * where a potential break is desired >= 0.
123      * @return the weight, which should be a value between
124      * ForcedBreakWeight and BadBreakWeight.
125      * @see LabelView
126      * @see ParagraphView
127      * @see javax.swing.text.View#BadBreakWeight
128      * @see javax.swing.text.View#GoodBreakWeight
129      * @see javax.swing.text.View#ExcellentBreakWeight
130      * @see javax.swing.text.View#ForcedBreakWeight
131      */

132     public int getBreakWeight(int axis, float pos, float len) {
133     if (nowrap) {
134         return BadBreakWeight;
135     }
136     return super.getBreakWeight(axis, pos, len);
137     }
138
139     /**
140      * Tries to break this view on the given axis. Refer to
141      * {@link javax.swing.text.View#breakView} for a complete
142      * description of this method.
143      * <p>Behavior of this method is unspecified in case <code>axis</code>
144      * is neither <code>View.X_AXIS</code> nor <code>View.Y_AXIS</code>, and
145      * in case <code>offset</code>, <code>pos</code>, or <code>len</code>
146      * is null.
147      *
148      * @param axis may be either <code>View.X_AXIS</code> or
149      * <code>View.Y_AXIS</code>
150      * @param offset the location in the document model
151      * that a broken fragment would occupy >= 0. This
152      * would be the starting offset of the fragment
153      * returned
154      * @param pos the position along the axis that the
155      * broken view would occupy >= 0. This may be useful for
156      * things like tab calculations
157      * @param len specifies the distance along the axis
158      * where a potential break is desired >= 0
159      * @return the fragment of the view that represents the
160      * given span.
161      * @since 1.5
162      * @see javax.swing.text.View#breakView
163      */

164     public View breakView(int axis, int offset, float pos, float len) {
165         InlineView JavaDoc view = (InlineView JavaDoc)super.breakView(axis, offset, pos, len);
166         if (view != this) {
167             view.longestWordSpan = -1;
168         }
169         return view;
170     }
171
172     /**
173      * Fetch the span of the longest word in the view.
174      */

175     float getLongestWordSpan() {
176         if (longestWordSpan < 0.0f) {
177             longestWordSpan = calculateLongestWordSpan();
178         }
179         return longestWordSpan;
180     }
181     
182     float calculateLongestWordSpan() {
183         float rv = 0f;
184         Document doc = getDocument();
185         //AbstractDocument.MultiByteProperty
186
final Object JavaDoc MultiByteProperty = "multiByte";
187         if (doc != null &&
188               Boolean.TRUE.equals(doc.getProperty(MultiByteProperty))) {
189             rv = calculateLongestWordSpanUseBreakIterator();
190         } else {
191             rv = calculateLongestWordSpanUseWhitespace();
192         }
193         return rv;
194     }
195
196     float calculateLongestWordSpanUseBreakIterator() {
197         float span = 0;
198         Document doc = getDocument();
199         int p0 = getStartOffset();
200         int p1 = getEndOffset();
201         if (p1 > p0) {
202             try {
203                 FontMetrics metrics = getFontMetrics();
204                 Segment segment = new Segment();
205                 doc.getText(p0, p1 - p0, segment);
206                 Container c = getContainer();
207                 BreakIterator JavaDoc line;
208                 if (c != null) {
209                     line = BreakIterator.getLineInstance(c.getLocale());
210                 } else {
211                     line = BreakIterator.getLineInstance();
212                 }
213                 line.setText(segment);
214                 int start = line.first();
215                 for (int end = line.next();
216                      end != BreakIterator.DONE;
217                      start = end, end = line.next()) {
218                      if (end > start) {
219                         span = Math.max(span,
220                            metrics.charsWidth(segment.array, start,
221                                                end - start));
222                     }
223                 }
224             } catch (BadLocationException ble) {
225               // If the text can't be retrieved, it can't influence the size.
226
}
227         }
228         return span;
229     }
230
231    float calculateLongestWordSpanUseWhitespace() {
232        float span = 0;
233        Document doc = getDocument();
234        int p0 = getStartOffset();
235        int p1 = getEndOffset();
236        if (p1 > p0) {
237            try {
238                Segment segment = new Segment();
239                doc.getText(p0, p1 - p0, segment);
240                final int CONTENT = 0;
241                final int SPACES = 1;
242                int state = CONTENT;
243                int start = segment.offset;
244                int end = start;
245                FontMetrics metrics = getFontMetrics();
246                final int lastIndex = segment.offset + segment.count - 1;
247                for (int i = segment.offset; i <= lastIndex; i++) {
248                    boolean updateSpan = false;
249                    if (Character.isWhitespace(segment.array[i])) {
250                        if (state == CONTENT) {
251                            //we got a word
252
updateSpan = true;
253                            state = SPACES;
254                        }
255                    } else {
256                        if (state == SPACES) {
257                            //first non space
258
start = i;
259                            end = start;
260                            state = CONTENT;
261                        } else {
262                            end = i;
263                        }
264                       //handle last word
265
if (i == lastIndex) {
266                            updateSpan = true;
267                        }
268                    }
269                    if (updateSpan) {
270                        if (end > start) {
271                            span = Math.max(span,
272                                metrics.charsWidth(segment.array, start,
273                                                   end - start + 1));
274                        }
275                    }
276
277                }
278            } catch (BadLocationException ble) {
279                // If the text can't be retrieved, it can't influence the size.
280
}
281        }
282        return span;
283   }
284     
285     /**
286      * Set the cached properties from the attributes.
287      */

288     protected void setPropertiesFromAttributes() {
289     super.setPropertiesFromAttributes();
290     AttributeSet a = getAttributes();
291     Object JavaDoc decor = a.getAttribute(CSS.Attribute.TEXT_DECORATION);
292     boolean u = (decor != null) ?
293       (decor.toString().indexOf("underline") >= 0) : false;
294     setUnderline(u);
295     boolean s = (decor != null) ?
296       (decor.toString().indexOf("line-through") >= 0) : false;
297     setStrikeThrough(s);
298         Object JavaDoc vAlign = a.getAttribute(CSS.Attribute.VERTICAL_ALIGN);
299     s = (vAlign != null) ? (vAlign.toString().indexOf("sup") >= 0) : false;
300     setSuperscript(s);
301     s = (vAlign != null) ? (vAlign.toString().indexOf("sub") >= 0) : false;
302     setSubscript(s);
303
304     Object JavaDoc whitespace = a.getAttribute(CSS.Attribute.WHITE_SPACE);
305     if ((whitespace != null) && whitespace.equals("nowrap")) {
306         nowrap = true;
307     } else {
308         nowrap = false;
309     }
310
311     HTMLDocument JavaDoc doc = (HTMLDocument JavaDoc)getDocument();
312     // fetches background color from stylesheet if specified
313
Color bg = doc.getBackground(a);
314     if (bg != null) {
315         setBackground(bg);
316     }
317     }
318
319
320     protected StyleSheet JavaDoc getStyleSheet() {
321     HTMLDocument JavaDoc doc = (HTMLDocument JavaDoc) getDocument();
322     return doc.getStyleSheet();
323     }
324
325     private boolean nowrap;
326     private AttributeSet attr;
327     private float longestWordSpan = -1.0f;
328 }
329
Popular Tags