Source Code Cross Referenced for PlainView.java in  » 6.0-JDK-Core » swing » javax » swing » text » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
Java Source Code / Java Documentation
1.6.0 JDK Core
2.6.0 JDK Modules
3.6.0 JDK Modules com.sun
4.6.0 JDK Modules com.sun.java
5.6.0 JDK Modules sun
6.6.0 JDK Platform
7.Ajax
8.Apache Harmony Java SE
9.Aspect oriented
10.Authentication Authorization
11.Blogger System
12.Build
13.Byte Code
14.Cache
15.Chart
16.Chat
17.Code Analyzer
18.Collaboration
19.Content Management System
20.Database Client
21.Database DBMS
22.Database JDBC Connection Pool
23.Database ORM
24.Development
25.EJB Server
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing.text 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025        package javax.swing.text;
026
027        import java.util.Vector;
028        import java.util.Properties;
029        import java.awt.*;
030        import javax.swing.event.*;
031
032        /**
033         * Implements View interface for a simple multi-line text view 
034         * that has text in one font and color.  The view represents each
035         * child element as a line of text.
036         *
037         * @author  Timothy Prinzing
038         * @version 1.84 05/05/07
039         * @see     View
040         */
041        public class PlainView extends View implements  TabExpander {
042
043            /**
044             * Constructs a new PlainView wrapped on an element.
045             *
046             * @param elem the element
047             */
048            public PlainView(Element elem) {
049                super (elem);
050            }
051
052            /**
053             * Returns the tab size set for the document, defaulting to 8.
054             *
055             * @return the tab size
056             */
057            protected int getTabSize() {
058                Integer i = (Integer) getDocument().getProperty(
059                        PlainDocument.tabSizeAttribute);
060                int size = (i != null) ? i.intValue() : 8;
061                return size;
062            }
063
064            /**
065             * Renders a line of text, suppressing whitespace at the end
066             * and expanding any tabs.  This is implemented to make calls
067             * to the methods <code>drawUnselectedText</code> and 
068             * <code>drawSelectedText</code> so that the way selected and 
069             * unselected text are rendered can be customized.
070             *
071             * @param lineIndex the line to draw >= 0
072             * @param g the <code>Graphics</code> context
073             * @param x the starting X position >= 0
074             * @param y the starting Y position >= 0
075             * @see #drawUnselectedText
076             * @see #drawSelectedText
077             */
078            protected void drawLine(int lineIndex, Graphics g, int x, int y) {
079                Element line = getElement().getElement(lineIndex);
080                Element elem;
081
082                try {
083                    if (line.isLeaf()) {
084                        drawElement(lineIndex, line, g, x, y);
085                    } else {
086                        // this line contains the composed text.
087                        int count = line.getElementCount();
088                        for (int i = 0; i < count; i++) {
089                            elem = line.getElement(i);
090                            x = drawElement(lineIndex, elem, g, x, y);
091                        }
092                    }
093                } catch (BadLocationException e) {
094                    throw new StateInvariantError("Can't render line: "
095                            + lineIndex);
096                }
097            }
098
099            private int drawElement(int lineIndex, Element elem, Graphics g,
100                    int x, int y) throws BadLocationException {
101                int p0 = elem.getStartOffset();
102                int p1 = elem.getEndOffset();
103                p1 = Math.min(getDocument().getLength(), p1);
104
105                if (lineIndex == 0) {
106                    x += firstLineOffset;
107                }
108                AttributeSet attr = elem.getAttributes();
109                if (Utilities.isComposedTextAttributeDefined(attr)) {
110                    g.setColor(unselected);
111                    x = Utilities
112                            .drawComposedText(this , attr, g, x, y, p0
113                                    - elem.getStartOffset(), p1
114                                    - elem.getStartOffset());
115                } else {
116                    if (sel0 == sel1 || selected == unselected) {
117                        // no selection, or it is invisible
118                        x = drawUnselectedText(g, x, y, p0, p1);
119                    } else if ((p0 >= sel0 && p0 <= sel1)
120                            && (p1 >= sel0 && p1 <= sel1)) {
121                        x = drawSelectedText(g, x, y, p0, p1);
122                    } else if (sel0 >= p0 && sel0 <= p1) {
123                        if (sel1 >= p0 && sel1 <= p1) {
124                            x = drawUnselectedText(g, x, y, p0, sel0);
125                            x = drawSelectedText(g, x, y, sel0, sel1);
126                            x = drawUnselectedText(g, x, y, sel1, p1);
127                        } else {
128                            x = drawUnselectedText(g, x, y, p0, sel0);
129                            x = drawSelectedText(g, x, y, sel0, p1);
130                        }
131                    } else if (sel1 >= p0 && sel1 <= p1) {
132                        x = drawSelectedText(g, x, y, p0, sel1);
133                        x = drawUnselectedText(g, x, y, sel1, p1);
134                    } else {
135                        x = drawUnselectedText(g, x, y, p0, p1);
136                    }
137                }
138
139                return x;
140            }
141
142            /**
143             * Renders the given range in the model as normal unselected
144             * text.  Uses the foreground or disabled color to render the text.
145             *
146             * @param g the graphics context
147             * @param x the starting X coordinate >= 0
148             * @param y the starting Y coordinate >= 0
149             * @param p0 the beginning position in the model >= 0
150             * @param p1 the ending position in the model >= 0
151             * @return the X location of the end of the range >= 0
152             * @exception BadLocationException if the range is invalid
153             */
154            protected int drawUnselectedText(Graphics g, int x, int y, int p0,
155                    int p1) throws BadLocationException {
156                g.setColor(unselected);
157                Document doc = getDocument();
158                Segment s = SegmentCache.getSharedSegment();
159                doc.getText(p0, p1 - p0, s);
160                int ret = Utilities.drawTabbedText(this , s, x, y, g, this , p0);
161                SegmentCache.releaseSharedSegment(s);
162                return ret;
163            }
164
165            /**
166             * Renders the given range in the model as selected text.  This
167             * is implemented to render the text in the color specified in
168             * the hosting component.  It assumes the highlighter will render
169             * the selected background.
170             *
171             * @param g the graphics context
172             * @param x the starting X coordinate >= 0
173             * @param y the starting Y coordinate >= 0
174             * @param p0 the beginning position in the model >= 0
175             * @param p1 the ending position in the model >= 0
176             * @return the location of the end of the range
177             * @exception BadLocationException if the range is invalid
178             */
179            protected int drawSelectedText(Graphics g, int x, int y, int p0,
180                    int p1) throws BadLocationException {
181                g.setColor(selected);
182                Document doc = getDocument();
183                Segment s = SegmentCache.getSharedSegment();
184                doc.getText(p0, p1 - p0, s);
185                int ret = Utilities.drawTabbedText(this , s, x, y, g, this , p0);
186                SegmentCache.releaseSharedSegment(s);
187                return ret;
188            }
189
190            /**
191             * Gives access to a buffer that can be used to fetch 
192             * text from the associated document.
193             *
194             * @return the buffer
195             */
196            protected final Segment getLineBuffer() {
197                if (lineBuffer == null) {
198                    lineBuffer = new Segment();
199                }
200                return lineBuffer;
201            }
202
203            /**
204             * Checks to see if the font metrics and longest line
205             * are up-to-date.
206             * 
207             * @since 1.4
208             */
209            protected void updateMetrics() {
210                Component host = getContainer();
211                Font f = host.getFont();
212                if (font != f) {
213                    // The font changed, we need to recalculate the
214                    // longest line.
215                    calculateLongestLine();
216                    tabSize = getTabSize() * metrics.charWidth('m');
217                }
218            }
219
220            // ---- View methods ----------------------------------------------------
221
222            /**
223             * Determines the preferred span for this view along an
224             * axis.
225             *
226             * @param axis may be either View.X_AXIS or View.Y_AXIS
227             * @return   the span the view would like to be rendered into >= 0.
228             *           Typically the view is told to render into the span
229             *           that is returned, although there is no guarantee.  
230             *           The parent may choose to resize or break the view.
231             * @exception IllegalArgumentException for an invalid axis
232             */
233            public float getPreferredSpan(int axis) {
234                updateMetrics();
235                switch (axis) {
236                case View.X_AXIS:
237                    return getLineWidth(longLine);
238                case View.Y_AXIS:
239                    return getElement().getElementCount() * metrics.getHeight();
240                default:
241                    throw new IllegalArgumentException("Invalid axis: " + axis);
242                }
243            }
244
245            /**
246             * Renders using the given rendering surface and area on that surface.
247             * The view may need to do layout and create child views to enable
248             * itself to render into the given allocation.
249             *
250             * @param g the rendering surface to use
251             * @param a the allocated region to render into
252             *
253             * @see View#paint
254             */
255            public void paint(Graphics g, Shape a) {
256                Shape originalA = a;
257                a = adjustPaintRegion(a);
258                Rectangle alloc = (Rectangle) a;
259                tabBase = alloc.x;
260                JTextComponent host = (JTextComponent) getContainer();
261                Highlighter h = host.getHighlighter();
262                g.setFont(host.getFont());
263                sel0 = host.getSelectionStart();
264                sel1 = host.getSelectionEnd();
265                unselected = (host.isEnabled()) ? host.getForeground() : host
266                        .getDisabledTextColor();
267                Caret c = host.getCaret();
268                selected = c.isSelectionVisible() && h != null ? host
269                        .getSelectedTextColor() : unselected;
270                updateMetrics();
271
272                // If the lines are clipped then we don't expend the effort to
273                // try and paint them.  Since all of the lines are the same height
274                // with this object, determination of what lines need to be repainted
275                // is quick.
276                Rectangle clip = g.getClipBounds();
277                int fontHeight = metrics.getHeight();
278                int heightBelow = (alloc.y + alloc.height)
279                        - (clip.y + clip.height);
280                int heightAbove = clip.y - alloc.y;
281                int linesBelow, linesAbove, linesTotal;
282
283                if (fontHeight > 0) {
284                    linesBelow = Math.max(0, heightBelow / fontHeight);
285                    linesAbove = Math.max(0, heightAbove / fontHeight);
286                    linesTotal = alloc.height / fontHeight;
287                    if (alloc.height % fontHeight != 0) {
288                        linesTotal++;
289                    }
290                } else {
291                    linesBelow = linesAbove = linesTotal = 0;
292                }
293
294                // update the visible lines
295                Rectangle lineArea = lineToRect(a, linesAbove);
296                int y = lineArea.y + metrics.getAscent();
297                int x = lineArea.x;
298                Element map = getElement();
299                int lineCount = map.getElementCount();
300                int endLine = Math.min(lineCount, linesTotal - linesBelow);
301                lineCount--;
302                LayeredHighlighter dh = (h instanceof  LayeredHighlighter) ? (LayeredHighlighter) h
303                        : null;
304                for (int line = linesAbove; line < endLine; line++) {
305                    if (dh != null) {
306                        Element lineElement = map.getElement(line);
307                        if (line == lineCount) {
308                            dh.paintLayeredHighlights(g, lineElement
309                                    .getStartOffset(), lineElement
310                                    .getEndOffset(), originalA, host, this );
311                        } else {
312                            dh.paintLayeredHighlights(g, lineElement
313                                    .getStartOffset(), lineElement
314                                    .getEndOffset() - 1, originalA, host, this );
315                        }
316                    }
317                    drawLine(line, g, x, y);
318                    y += fontHeight;
319                    if (line == 0) {
320                        // This should never really happen, in so far as if
321                        // firstLineOffset is non 0, there should only be one
322                        // line of text.
323                        x -= firstLineOffset;
324                    }
325                }
326            }
327
328            /**
329             * Should return a shape ideal for painting based on the passed in
330             * Shape <code>a</code>. This is useful if painting in a different
331             * region. The default implementation returns <code>a</code>.
332             */
333            Shape adjustPaintRegion(Shape a) {
334                return a;
335            }
336
337            /**
338             * Provides a mapping from the document model coordinate space
339             * to the coordinate space of the view mapped to it.
340             *
341             * @param pos the position to convert >= 0
342             * @param a the allocated region to render into
343             * @return the bounding box of the given position
344             * @exception BadLocationException  if the given position does not
345             *   represent a valid location in the associated document
346             * @see View#modelToView
347             */
348            public Shape modelToView(int pos, Shape a, Position.Bias b)
349                    throws BadLocationException {
350                // line coordinates
351                Document doc = getDocument();
352                Element map = getElement();
353                int lineIndex = map.getElementIndex(pos);
354                if (lineIndex < 0) {
355                    return lineToRect(a, 0);
356                }
357                Rectangle lineArea = lineToRect(a, lineIndex);
358
359                // determine span from the start of the line
360                tabBase = lineArea.x;
361                Element line = map.getElement(lineIndex);
362                int p0 = line.getStartOffset();
363                Segment s = SegmentCache.getSharedSegment();
364                doc.getText(p0, pos - p0, s);
365                int xOffs = Utilities.getTabbedTextWidth(s, metrics, tabBase,
366                        this , p0);
367                SegmentCache.releaseSharedSegment(s);
368
369                // fill in the results and return
370                lineArea.x += xOffs;
371                lineArea.width = 1;
372                lineArea.height = metrics.getHeight();
373                return lineArea;
374            }
375
376            /**
377             * Provides a mapping from the view coordinate space to the logical
378             * coordinate space of the model.
379             *
380             * @param fx the X coordinate >= 0
381             * @param fy the Y coordinate >= 0
382             * @param a the allocated region to render into
383             * @return the location within the model that best represents the
384             *  given point in the view >= 0
385             * @see View#viewToModel
386             */
387            public int viewToModel(float fx, float fy, Shape a,
388                    Position.Bias[] bias) {
389                // PENDING(prinz) properly calculate bias
390                bias[0] = Position.Bias.Forward;
391
392                Rectangle alloc = a.getBounds();
393                Document doc = getDocument();
394                int x = (int) fx;
395                int y = (int) fy;
396                if (y < alloc.y) {
397                    // above the area covered by this icon, so the the position
398                    // is assumed to be the start of the coverage for this view.
399                    return getStartOffset();
400                } else if (y > alloc.y + alloc.height) {
401                    // below the area covered by this icon, so the the position
402                    // is assumed to be the end of the coverage for this view.
403                    return getEndOffset() - 1;
404                } else {
405                    // positioned within the coverage of this view vertically,
406                    // so we figure out which line the point corresponds to.
407                    // if the line is greater than the number of lines contained, then
408                    // simply use the last line as it represents the last possible place
409                    // we can position to.
410                    Element map = doc.getDefaultRootElement();
411                    int fontHeight = metrics.getHeight();
412                    int lineIndex = (fontHeight > 0 ? Math.abs((y - alloc.y)
413                            / fontHeight) : map.getElementCount() - 1);
414                    if (lineIndex >= map.getElementCount()) {
415                        return getEndOffset() - 1;
416                    }
417                    Element line = map.getElement(lineIndex);
418                    int dx = 0;
419                    if (lineIndex == 0) {
420                        alloc.x += firstLineOffset;
421                        alloc.width -= firstLineOffset;
422                    }
423                    if (x < alloc.x) {
424                        // point is to the left of the line
425                        return line.getStartOffset();
426                    } else if (x > alloc.x + alloc.width) {
427                        // point is to the right of the line
428                        return line.getEndOffset() - 1;
429                    } else {
430                        // Determine the offset into the text
431                        try {
432                            int p0 = line.getStartOffset();
433                            int p1 = line.getEndOffset() - 1;
434                            Segment s = SegmentCache.getSharedSegment();
435                            doc.getText(p0, p1 - p0, s);
436                            tabBase = alloc.x;
437                            int offs = p0
438                                    + Utilities.getTabbedTextOffset(s, metrics,
439                                            tabBase, x, this , p0);
440                            SegmentCache.releaseSharedSegment(s);
441                            return offs;
442                        } catch (BadLocationException e) {
443                            // should not happen
444                            return -1;
445                        }
446                    }
447                }
448            }
449
450            /**
451             * Gives notification that something was inserted into the document
452             * in a location that this view is responsible for.
453             *
454             * @param changes the change information from the associated document
455             * @param a the current allocation of the view
456             * @param f the factory to use to rebuild if the view has children
457             * @see View#insertUpdate
458             */
459            public void insertUpdate(DocumentEvent changes, Shape a,
460                    ViewFactory f) {
461                updateDamage(changes, a, f);
462            }
463
464            /**
465             * Gives notification that something was removed from the document
466             * in a location that this view is responsible for.
467             *
468             * @param changes the change information from the associated document
469             * @param a the current allocation of the view
470             * @param f the factory to use to rebuild if the view has children
471             * @see View#removeUpdate
472             */
473            public void removeUpdate(DocumentEvent changes, Shape a,
474                    ViewFactory f) {
475                updateDamage(changes, a, f);
476            }
477
478            /**
479             * Gives notification from the document that attributes were changed
480             * in a location that this view is responsible for.
481             *
482             * @param changes the change information from the associated document
483             * @param a the current allocation of the view
484             * @param f the factory to use to rebuild if the view has children
485             * @see View#changedUpdate
486             */
487            public void changedUpdate(DocumentEvent changes, Shape a,
488                    ViewFactory f) {
489                updateDamage(changes, a, f);
490            }
491
492            /**
493             * Sets the size of the view.  This should cause 
494             * layout of the view along the given axis, if it 
495             * has any layout duties.
496             *
497             * @param width the width >= 0
498             * @param height the height >= 0
499             */
500            public void setSize(float width, float height) {
501                super .setSize(width, height);
502                updateMetrics();
503            }
504
505            // --- TabExpander methods ------------------------------------------
506
507            /**
508             * Returns the next tab stop position after a given reference position.
509             * This implementation does not support things like centering so it
510             * ignores the tabOffset argument.
511             *
512             * @param x the current position >= 0
513             * @param tabOffset the position within the text stream
514             *   that the tab occurred at >= 0.
515             * @return the tab stop, measured in points >= 0
516             */
517            public float nextTabStop(float x, int tabOffset) {
518                if (tabSize == 0) {
519                    return x;
520                }
521                int ntabs = (((int) x) - tabBase) / tabSize;
522                return tabBase + ((ntabs + 1) * tabSize);
523            }
524
525            // --- local methods ------------------------------------------------
526
527            /**
528             * Repaint the region of change covered by the given document
529             * event.  Damages the line that begins the range to cover
530             * the case when the insert/remove is only on one line.  
531             * If lines are added or removed, damages the whole 
532             * view.  The longest line is checked to see if it has 
533             * changed.
534             *
535             * @since 1.4
536             */
537            protected void updateDamage(DocumentEvent changes, Shape a,
538                    ViewFactory f) {
539                Component host = getContainer();
540                updateMetrics();
541                Element elem = getElement();
542                DocumentEvent.ElementChange ec = changes.getChange(elem);
543
544                Element[] added = (ec != null) ? ec.getChildrenAdded() : null;
545                Element[] removed = (ec != null) ? ec.getChildrenRemoved()
546                        : null;
547                if (((added != null) && (added.length > 0))
548                        || ((removed != null) && (removed.length > 0))) {
549                    // lines were added or removed...
550                    if (added != null) {
551                        int currWide = getLineWidth(longLine);
552                        for (int i = 0; i < added.length; i++) {
553                            int w = getLineWidth(added[i]);
554                            if (w > currWide) {
555                                currWide = w;
556                                longLine = added[i];
557                            }
558                        }
559                    }
560                    if (removed != null) {
561                        for (int i = 0; i < removed.length; i++) {
562                            if (removed[i] == longLine) {
563                                calculateLongestLine();
564                                break;
565                            }
566                        }
567                    }
568                    preferenceChanged(null, true, true);
569                    host.repaint();
570                } else {
571                    Element map = getElement();
572                    int line = map.getElementIndex(changes.getOffset());
573                    damageLineRange(line, line, a, host);
574                    if (changes.getType() == DocumentEvent.EventType.INSERT) {
575                        // check to see if the line is longer than current
576                        // longest line.
577                        int w = getLineWidth(longLine);
578                        Element e = map.getElement(line);
579                        if (e == longLine) {
580                            preferenceChanged(null, true, false);
581                        } else if (getLineWidth(e) > w) {
582                            longLine = e;
583                            preferenceChanged(null, true, false);
584                        }
585                    } else if (changes.getType() == DocumentEvent.EventType.REMOVE) {
586                        if (map.getElement(line) == longLine) {
587                            // removed from longest line... recalc
588                            calculateLongestLine();
589                            preferenceChanged(null, true, false);
590                        }
591                    }
592                }
593            }
594
595            /**
596             * Repaint the given line range.
597             *
598             * @param host the component hosting the view (used to call repaint)
599             * @param a  the region allocated for the view to render into
600             * @param line0 the starting line number to repaint.  This must
601             *   be a valid line number in the model.
602             * @param line1 the ending line number to repaint.  This must
603             *   be a valid line number in the model.
604             * @since 1.4
605             */
606            protected void damageLineRange(int line0, int line1, Shape a,
607                    Component host) {
608                if (a != null) {
609                    Rectangle area0 = lineToRect(a, line0);
610                    Rectangle area1 = lineToRect(a, line1);
611                    if ((area0 != null) && (area1 != null)) {
612                        Rectangle damage = area0.union(area1);
613                        host.repaint(damage.x, damage.y, damage.width,
614                                damage.height);
615                    } else {
616                        host.repaint();
617                    }
618                }
619            }
620
621            /**
622             * Determine the rectangle that represents the given line.
623             *
624             * @param a  the region allocated for the view to render into
625             * @param line the line number to find the region of.  This must
626             *   be a valid line number in the model.
627             * @since 1.4
628             */
629            protected Rectangle lineToRect(Shape a, int line) {
630                Rectangle r = null;
631                updateMetrics();
632                if (metrics != null) {
633                    Rectangle alloc = a.getBounds();
634                    if (line == 0) {
635                        alloc.x += firstLineOffset;
636                        alloc.width -= firstLineOffset;
637                    }
638                    r = new Rectangle(alloc.x, alloc.y
639                            + (line * metrics.getHeight()), alloc.width,
640                            metrics.getHeight());
641                }
642                return r;
643            }
644
645            /**
646             * Iterate over the lines represented by the child elements
647             * of the element this view represents, looking for the line
648             * that is the longest.  The <em>longLine</em> variable is updated to
649             * represent the longest line contained.  The <em>font</em> variable
650             * is updated to indicate the font used to calculate the 
651             * longest line.
652             */
653            private void calculateLongestLine() {
654                Component c = getContainer();
655                font = c.getFont();
656                metrics = c.getFontMetrics(font);
657                Document doc = getDocument();
658                Element lines = getElement();
659                int n = lines.getElementCount();
660                int maxWidth = -1;
661                for (int i = 0; i < n; i++) {
662                    Element line = lines.getElement(i);
663                    int w = getLineWidth(line);
664                    if (w > maxWidth) {
665                        maxWidth = w;
666                        longLine = line;
667                    }
668                }
669            }
670
671            /**
672             * Calculate the width of the line represented by
673             * the given element.  It is assumed that the font
674             * and font metrics are up-to-date.
675             */
676            private int getLineWidth(Element line) {
677                if (line == null) {
678                    return 0;
679                }
680                int p0 = line.getStartOffset();
681                int p1 = line.getEndOffset();
682                int w;
683                Segment s = SegmentCache.getSharedSegment();
684                try {
685                    line.getDocument().getText(p0, p1 - p0, s);
686                    w = Utilities.getTabbedTextWidth(s, metrics, tabBase, this ,
687                            p0);
688                } catch (BadLocationException ble) {
689                    w = 0;
690                }
691                SegmentCache.releaseSharedSegment(s);
692                return w;
693            }
694
695            // --- member variables -----------------------------------------------
696
697            /**
698             * Font metrics for the current font.
699             */
700            protected FontMetrics metrics;
701
702            /**
703             * The current longest line.  This is used to calculate
704             * the preferred width of the view.  Since the calculation
705             * is potentially expensive we try to avoid it by stashing
706             * which line is currently the longest.
707             */
708            Element longLine;
709
710            /**
711             * Font used to calculate the longest line... if this 
712             * changes we need to recalculate the longest line
713             */
714            Font font;
715
716            Segment lineBuffer;
717            int tabSize;
718            int tabBase;
719
720            int sel0;
721            int sel1;
722            Color unselected;
723            Color selected;
724
725            /**
726             * Offset of where to draw the first character on the first line.
727             * This is a hack and temporary until we can better address the problem
728             * of text measuring. This field is actually never set directly in
729             * PlainView, but by FieldView.
730             */
731            int firstLineOffset;
732
733        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.