Source Code Cross Referenced for TextComponent.java in  » Internationalization-Localization » icu4j » com » ibm » richtext » textpanel » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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 geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Internationalization Localization » icu4j » com.ibm.richtext.textpanel 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * (C) Copyright IBM Corp. 1998-2005.  All Rights Reserved.
003:         *
004:         * The program is provided "as is" without any warranty express or
005:         * implied, including the warranty of non-infringement and the implied
006:         * warranties of merchantibility and fitness for a particular purpose.
007:         * IBM will not be liable for any damages suffered by you as a result
008:         * of using the Program. In no event will IBM be liable for any
009:         * special, indirect or consequential damages or lost profits even if
010:         * IBM has been advised of the possibility of their occurrence. IBM
011:         * will not be liable for any third party claims against you.
012:         */
013:        package com.ibm.richtext.textpanel;
014:
015:        import java.awt.Color;
016:        import java.awt.Component;
017:        import java.awt.Graphics;
018:        import java.awt.Image;
019:        import java.awt.Point;
020:        import java.awt.Rectangle;
021:
022:        import java.awt.event.ComponentAdapter;
023:        import java.awt.event.FocusListener;
024:        import java.awt.event.KeyListener;
025:        import java.awt.event.MouseListener;
026:        import java.awt.event.MouseMotionListener;
027:
028:        import java.awt.event.ComponentEvent;
029:        import java.awt.event.FocusEvent;
030:        import java.awt.event.KeyEvent;
031:        import java.awt.event.MouseEvent;
032:
033:        import com.ibm.richtext.styledtext.MConstText;
034:        import com.ibm.richtext.styledtext.MText;
035:        import com.ibm.richtext.textformat.TextOffset;
036:
037:        import com.ibm.richtext.textformat.MFormatter;
038:
039:        import com.ibm.richtext.textlayout.attributes.AttributeMap;
040:
041:        class TextComponent extends FakeComponent implements  BehaviorOwner,
042:                FocusListener, KeyListener, MouseListener, MouseMotionListener,
043:                Scroller.Client {
044:
045:            static final String COPYRIGHT = "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
046:
047:            public static final int WINDOW_WIDTH = -10;
048:            public static final int DEFAULT_INSET = 10;
049:
050:            private static final Color STRONG_CARET_COLOR = Color.black;
051:            private static final Color WEAK_CARET_COLOR = Color.darkGray;
052:
053:            private Behavior fBehavior;
054:            private MText fText;
055:            private StyledTextClipboard fClipboard;
056:            private boolean fScrolls;
057:            private Scroller fScroller;
058:
059:            private DocumentView fDocumentView = null;
060:
061:            // sigh - can't create DocumentView until addNotify() is called.
062:            // These values hold DocumentView ctor args
063:            private AttributeMap fDefaultValues;
064:            private boolean fViewWraps;
065:            private int fViewWrapWidth;
066:            private int fViewInsetAmount;
067:
068:            private PanelEventBroadcaster fListener;
069:
070:            /**
071:             * Create a new TextComponent.
072:             * @param text the text model.  This model will be used for
073:             * the life of the component, even if setText is called
074:             * @param wraps if true, the text is wrapped to the specified
075:             * wrapping width.  If false, the text wraps only at paragraph breaks.
076:             * @param wrapWidth ignored if wraps is false.  Text wraps to this width
077:             * unless the width is WINDOW_WIDTH, in which case text wraps to width
078:             * of this component. Should not be negative (unless it is WINDOW_WIDTH).
079:             * @param insetAmount the size of the margins around the text
080:             * @param clipboard the clipboard to use for cut/copy/paste operations.
081:             * If null, the component will use its own clipboard.
082:             */
083:            public TextComponent(MText text, AttributeMap defaultValues,
084:                    boolean wraps, int wrapWidth, int insetAmount,
085:                    StyledTextClipboard clipboard, boolean scrolls,
086:                    Scroller scroller, PanelEventBroadcaster listener) {
087:
088:                fBehavior = null;
089:
090:                if (text == null) {
091:                    throw new IllegalArgumentException("Text is null.");
092:                }
093:
094:                fText = text;
095:                fDefaultValues = defaultValues;
096:
097:                if (clipboard == null) {
098:                    throw new IllegalArgumentException("Clipboard is null.");
099:                }
100:                fClipboard = clipboard;
101:
102:                fScrolls = scrolls;
103:
104:                fScroller = scroller;
105:
106:                fDocumentView = null;
107:
108:                fViewWrapWidth = wrapWidth;
109:                fViewWraps = wraps;
110:                fViewInsetAmount = insetAmount;
111:                fListener = listener;
112:            }
113:
114:            AttributeMap getDefaultValues() {
115:
116:                return fDefaultValues;
117:            }
118:
119:            void setHost(Component component) {
120:
121:                super .setHost(component);
122:
123:                component.addFocusListener(this );
124:                component.addKeyListener(this );
125:                component.addMouseListener(this );
126:                component.addMouseMotionListener(this );
127:
128:                component.addComponentListener(new ComponentAdapter() {
129:                    public void componentResized(ComponentEvent e) {
130:                        if (fDocumentView != null) {
131:                            fDocumentView.hostSizeChanged();
132:                            scrollToShow(fDocumentView.getDocumentBounds());
133:                        }
134:                    }
135:                });
136:            }
137:
138:            /**
139:             * ATextPanelImpl's use only!
140:             */
141:            Component getHost() {
142:
143:                return fHost;
144:            }
145:
146:            // Create document view here.  TextComponent isn't fully constructed
147:            // until this is called.
148:            // This must be called by host component!
149:            void addNotify() {
150:
151:                Graphics g = getGraphics();
152:                if (g == null) {
153:                    throw new Error("Graphics should be valid here but isn't.");
154:                }
155:
156:                fDocumentView = new DocumentView(this , fText, fDefaultValues,
157:                        fViewWraps, fViewWrapWidth, fViewInsetAmount, fListener);
158:                documentSizeChanged();
159:                fListener.textStateChanged(TextPanelEvent.FORMAT_WIDTH_CHANGED);
160:            }
161:
162:            public Rectangle getBounds() {
163:
164:                if (fHost != null) {
165:                    return fHost.getBounds();
166:                }
167:                return new Rectangle(0, 0, 0, 0);
168:            }
169:
170:            Graphics getGraphics() {
171:
172:                return (fHost == null) ? null : fHost.getGraphics();
173:            }
174:
175:            void requestFocus() {
176:
177:                if (fHost != null) {
178:                    fHost.requestFocus();
179:                }
180:            }
181:
182:            // *** Behavior management ***
183:            public Behavior getBehavior() {
184:                return fBehavior;
185:            }
186:
187:            public void setBehavior(Behavior b) {
188:                fBehavior = b;
189:            }
190:
191:            // *** Events - just forward to behavior ***
192:            public void focusGained(FocusEvent event) {
193:                if (fBehavior != null)
194:                    fBehavior.focusGained(event);
195:            }
196:
197:            public void focusLost(FocusEvent event) {
198:                if (fBehavior != null)
199:                    fBehavior.focusLost(event);
200:            }
201:
202:            public void keyPressed(KeyEvent event) {
203:                if (fBehavior != null)
204:                    fBehavior.keyPressed(event);
205:            }
206:
207:            public void keyTyped(KeyEvent event) {
208:
209:                if (fBehavior != null) {
210:                    fBehavior.keyTyped(event);
211:                }
212:            }
213:
214:            public void keyReleased(KeyEvent event) {
215:                if (fBehavior != null)
216:                    fBehavior.keyReleased(event);
217:            }
218:
219:            public void mouseClicked(MouseEvent event) {
220:                // no behavior method for this
221:            }
222:
223:            public void mouseDragged(MouseEvent event) {
224:                if (fBehavior != null)
225:                    fBehavior.mouseDragged(event);
226:            }
227:
228:            public void mouseEntered(MouseEvent event) {
229:                if (fBehavior != null)
230:                    fBehavior.mouseEntered(event);
231:            }
232:
233:            public void mouseExited(MouseEvent event) {
234:                if (fBehavior != null)
235:                    fBehavior.mouseExited(event);
236:            }
237:
238:            public void mouseMoved(MouseEvent event) {
239:                if (fBehavior != null)
240:                    fBehavior.mouseMoved(event);
241:            }
242:
243:            public void mousePressed(MouseEvent event) {
244:                if (fBehavior != null)
245:                    fBehavior.mousePressed(event);
246:            }
247:
248:            public void mouseReleased(MouseEvent event) {
249:                if (fBehavior != null)
250:                    fBehavior.mouseReleased(event);
251:            }
252:
253:            public boolean textControlEventOccurred(Behavior.EventType event,
254:                    Object what) {
255:
256:                boolean handled = false;
257:
258:                if (fBehavior != null) {
259:                    handled = fBehavior.textControlEventOccurred(event, what);
260:                }
261:                return handled;
262:            }
263:
264:            // *** Scroll methods - called by Behaviors
265:
266:            // viewStart, viewLimit is visible bounds of window
267:            // targetStart, targetLimit is the region to scroll into view
268:            private static int getScrollDifference(int viewStart,
269:                    int viewLimit, int targetStart, int targetLimit) {
270:
271:                if (viewStart <= targetStart) {
272:                    if (viewLimit >= targetLimit) {
273:                        return 0;
274:                    }
275:                    return Math.max(viewStart - targetStart, viewLimit
276:                            - targetLimit);
277:                } else if (viewLimit > targetLimit) {
278:
279:                    return viewLimit - targetLimit;
280:                } else {
281:                    return 0;
282:                }
283:            }
284:
285:            void scrollToShow(Rectangle showRect) {
286:
287:                if (fDocumentView != null) {
288:                    Rectangle bounds = getBounds();
289:
290:                    int dx = getScrollDifference(showRect.x, showRect.x
291:                            + showRect.width, bounds.x, bounds.x + bounds.width);
292:                    int dy = getScrollDifference(showRect.y, showRect.y
293:                            + showRect.height, bounds.y, bounds.y
294:                            + bounds.height);
295:
296:                    scrollSelf(dx, dy);
297:                }
298:            }
299:
300:            void scrollToShow(int showX, int showY) {
301:
302:                if (fDocumentView != null) {
303:                    int dx = 0, dy = 0;
304:
305:                    Rectangle bounds = getBounds();
306:                    if (showX < bounds.x) {
307:                        dx = showX - bounds.x;
308:                    } else if (showX > bounds.x + bounds.width) {
309:                        dx = showX - (bounds.x + bounds.width);
310:                    }
311:
312:                    if (showY < bounds.y) {
313:                        dy = showY - bounds.y;
314:                    } else if (showY > bounds.y + bounds.height) {
315:                        dy = showY - (bounds.y + bounds.height);
316:                    }
317:
318:                    scrollSelf(dx, dy);
319:                }
320:            }
321:
322:            private int pinScrollOffset(int delta, int contentStart,
323:                    int contentLength, int viewStart, int viewLength) {
324:
325:                if (delta > 0) {
326:                    int viewLimit = viewStart + viewLength;
327:                    int contentLimit = contentStart + contentLength;
328:
329:                    if (viewLimit + delta > contentLimit) {
330:                        delta = Math.max(0, contentLimit - viewLimit);
331:                    }
332:                } else {
333:                    if (viewStart + delta < contentStart) {
334:                        delta = Math.min(0, contentStart - viewStart);
335:                    }
336:                }
337:
338:                return delta;
339:            }
340:
341:            private void scrollSelf(int dx, int dy) {
342:
343:                boolean scrolled = scrollBy(dx, dy);
344:
345:                if (scrolled && fScroller != null) {
346:                    Rectangle documentBounds = fDocumentView
347:                            .getDocumentBounds();
348:                    fScroller.setPosition(-documentBounds.x, -documentBounds.y);
349:                }
350:            }
351:
352:            private synchronized boolean scrollBy(int dx, int dy) {
353:
354:                boolean scrolled = false;
355:
356:                if (fScrolls) {
357:                    Rectangle documentBounds = fDocumentView
358:                            .getDocumentBounds();
359:                    Rectangle viewBounds = getBounds();
360:
361:                    // variable not used int oldDx = dx;
362:                    dx = pinScrollOffset(dx, documentBounds.x,
363:                            documentBounds.width, viewBounds.x,
364:                            viewBounds.width);
365:                    dy = pinScrollOffset(dy, documentBounds.y,
366:                            documentBounds.height, viewBounds.y,
367:                            viewBounds.height);
368:
369:                    if (dx != 0 || dy != 0) {
370:                        scrolled = true;
371:                        fDocumentView.moveBy(-dx, -dy);
372:                    }
373:                }
374:
375:                return scrolled;
376:            }
377:
378:            // implementation of Scroller.Client - called by Scroller
379:            // they have to be public since they're in an interface
380:            // no one else should call these methods
381:            public Rectangle getScrollSize() {
382:
383:                if (fDocumentView != null) {
384:                    return fDocumentView.getScrollableArea();
385:                }
386:                return new Rectangle(0, 0, 0, 0);
387:            }
388:
389:            public void scrollTo(int x, int y) {
390:
391:                if (fDocumentView != null) {
392:                    scrollBy(x + fDocumentView.getDocX(), y
393:                            + fDocumentView.getDocY());
394:                }
395:            }
396:
397:            // *** Text access ***
398:            MConstText getText() {
399:                return fText;
400:            }
401:
402:            MText getModifiableText() {
403:                return fText;
404:            }
405:
406:            StyledTextClipboard getClipboard() {
407:                return fClipboard;
408:            }
409:
410:            public synchronized void paint(Graphics g) {
411:
412:                if (fDocumentView != null) {
413:                    fDocumentView.paint(g);
414:                }
415:            }
416:
417:            // *** Metric info - used by Behaviors
418:            Rectangle getCaretRect(TextOffset offset) {
419:
420:                if (fDocumentView != null) {
421:                    return fDocumentView.getCaretRect(offset);
422:                }
423:                return new Rectangle(0, 0);
424:            }
425:
426:            TextOffset pointToTextOffset(TextOffset result, int x, int y,
427:                    TextOffset anchor, boolean infiniteMode) {
428:
429:                if (fDocumentView != null) {
430:                    return fDocumentView.pointToTextOffset(result, x, y,
431:                            anchor, infiniteMode);
432:                }
433:                return new TextOffset();
434:            }
435:
436:            // *** Other stuff used by Behaviors - mostly formatter exports
437:            int lineContaining(TextOffset offset) {
438:
439:                if (fDocumentView != null) {
440:                    return fDocumentView.lineContaining(offset);
441:                }
442:                return 0;
443:            }
444:
445:            int lineRangeLow(int lineNumber) {
446:
447:                if (fDocumentView != null) {
448:                    return fDocumentView.lineRangeLow(lineNumber);
449:                }
450:                return 0;
451:            }
452:
453:            int lineRangeLimit(int lineNumber) {
454:
455:                if (fDocumentView != null) {
456:                    return fDocumentView.lineRangeLimit(lineNumber);
457:                }
458:                return 0;
459:            }
460:
461:            void stopBackgroundFormatting() {
462:
463:                if (fDocumentView != null) {
464:                    fDocumentView.stopBackgroundFormatting();
465:                }
466:            }
467:
468:            Rectangle getBoundingRect(TextOffset offset1, TextOffset offset2) {
469:
470:                if (fDocumentView != null) {
471:                    return fDocumentView.getBoundingRect(offset1, offset2);
472:                }
473:                return new Rectangle(0, 0, 0, 0);
474:            }
475:
476:            synchronized void reformatAndDrawText(int reformatStart,
477:                    int reformatLength, TextOffset selStart, TextOffset selEnd,
478:                    Rectangle additionalUpdateRect, Color hiliteColor) {
479:
480:                if (fDocumentView != null) {
481:                    fDocumentView.reformatAndDrawText(reformatStart,
482:                            reformatLength, selStart, selEnd,
483:                            additionalUpdateRect, hiliteColor);
484:                }
485:            }
486:
487:            TextOffset findNewInsertionOffset(TextOffset result,
488:                    TextOffset initialOffset, TextOffset previousOffset,
489:                    short direction) {
490:
491:                if (fDocumentView != null) {
492:                    return fDocumentView.findNewInsertionOffset(result,
493:                            initialOffset, previousOffset, direction);
494:                }
495:                return new TextOffset(initialOffset);
496:            }
497:
498:            synchronized void drawText(Graphics g, Rectangle damagedRect,
499:                    boolean selectionVisible, TextOffset selStart,
500:                    TextOffset selEnd, Color hiliteColor) {
501:
502:                if (fDocumentView != null) {
503:                    fDocumentView.drawText(g, damagedRect, selectionVisible,
504:                            selStart, selEnd, hiliteColor);
505:                }
506:            }
507:
508:            private void documentSizeChanged() {
509:
510:                if (fScroller != null) {
511:                    fScroller.clientScrollSizeChanged();
512:                }
513:            }
514:
515:            int getFormatWidth() {
516:
517:                if (fDocumentView != null) {
518:                    return fDocumentView.getFormatWidth();
519:                }
520:                return 0;
521:            }
522:
523:            /**
524:             * Return true if the paragraph at the given offset is left-to-right.
525:             * @param offset an offset in the text
526:             * @return true if the paragraph at the given offset is left-to-right
527:             */
528:            boolean paragraphIsLeftToRight(int offset) {
529:
530:                if (fDocumentView != null) {
531:                    return fDocumentView.paragraphIsLeftToRight(offset);
532:                }
533:                return true;
534:            }
535:
536:            private static final class DocumentView {
537:
538:                private TextComponent fHost;
539:                private boolean fWraps;
540:                private boolean fWrapToWindowWidth;
541:                private int fInsetAmount;
542:                private PanelEventBroadcaster fListener;
543:
544:                // fBounds is the total scrollable area of the document (including insets)
545:                private Rectangle fBounds = new Rectangle();
546:
547:                private Point fOrigin;
548:
549:                private MFormatter fFormatter;
550:
551:                private OffscreenBufferCache fBufferCache;
552:
553:                // Note, when this is true the caret won't blink in 1.1.  Looks like an AWT bug.
554:                private static boolean fNoOffscreenBuffer = Boolean
555:                        .getBoolean("TextComponent.NoOffscreenBuffer");
556:
557:                // Amount by which to reduce the format width to allow for right-aligned carets.
558:                private final int CARET_SLOP = 1;
559:
560:                DocumentView(TextComponent host, MConstText text,
561:                        AttributeMap defaultValues, boolean wraps,
562:                        int wrapWidth, int insetAmount,
563:                        PanelEventBroadcaster listener) {
564:
565:                    fHost = host;
566:                    fWrapToWindowWidth = wrapWidth == WINDOW_WIDTH;
567:                    fInsetAmount = insetAmount;
568:                    fListener = listener;
569:
570:                    initFormatterAndSize(text, defaultValues, wraps, wrapWidth);
571:
572:                    fBufferCache = new OffscreenBufferCache(host.fHost);
573:                }
574:
575:                /**
576:                 * Note: this computes the bounds rectangle relative to fOrigin
577:                 */
578:                private void calcBoundsRect() {
579:
580:                    final int insetDim = 2 * fInsetAmount;
581:
582:                    final int minX = fFormatter.minX();
583:                    final int minY = fFormatter.minY();
584:
585:                    fBounds.setBounds(fOrigin.x + minX - fInsetAmount,
586:                            fOrigin.y + minY - fInsetAmount, fFormatter.maxX()
587:                                    - minX + insetDim, fFormatter.maxY() - minY
588:                                    + insetDim);
589:                    //if (minX <= 0) {
590:                    //    System.out.println("calcBoundsRect: minX="+minX+
591:                    //                       "; bounds.x="+fBounds.x+"; width="+fBounds.width);
592:                    //}
593:                }
594:
595:                private void initFormatterAndSize(MConstText text,
596:                        AttributeMap defaultValues, boolean wraps, int wrapWidth) {
597:
598:                    Rectangle hostBounds = fHost.getBounds();
599:                    int formatWidth;
600:
601:                    if (!wraps || fWrapToWindowWidth) {
602:                        formatWidth = hostBounds.width - 2 * fInsetAmount;
603:                        if (formatWidth <= CARET_SLOP) {
604:                            formatWidth = CARET_SLOP + 1;
605:                        }
606:                    } else {
607:                        formatWidth = wrapWidth;
608:                    }
609:
610:                    fFormatter = MFormatter.createFormatter(text,
611:                            defaultValues, formatWidth - CARET_SLOP, wraps,
612:                            fHost.getGraphics());
613:
614:                    fFormatter.formatToHeight(hostBounds.height * 2);
615:                    fOrigin = new Point(fInsetAmount, fInsetAmount);
616:                    calcBoundsRect();
617:                }
618:
619:                // notification method called by TextComponent
620:                void hostSizeChanged() {
621:
622:                    final boolean wrap = fFormatter.wrap();
623:                    if (fWrapToWindowWidth || !wrap) {
624:
625:                        Rectangle hostBounds = fHost.getBounds();
626:                        // variable not used final int insetDim = 2 * fInsetAmount;
627:
628:                        int formatWidth = hostBounds.width - 2 * fInsetAmount;
629:                        if (formatWidth <= CARET_SLOP) {
630:                            formatWidth = CARET_SLOP + 1;
631:                        }
632:                        fFormatter.setLineBound(formatWidth - CARET_SLOP);
633:
634:                        fFormatter.formatToHeight(hostBounds.y
635:                                + (hostBounds.height * 2) - fOrigin.y);
636:
637:                        calcBoundsRect();
638:
639:                        //System.out.println("Window bounds="+hostBounds+"; document bounds="+fBounds);
640:
641:                        fHost.documentSizeChanged();
642:                        fListener
643:                                .textStateChanged(TextPanelEvent.FORMAT_WIDTH_CHANGED);
644:                        //System.out.println("formatWidth="+formatWidth);
645:                        //System.out.println("document bounds="+fBounds);
646:                        //System.out.println();
647:                    }
648:                    //dumpWidthInfo();
649:                }
650:
651:                int getFormatWidth() {
652:
653:                    return fFormatter.lineBound();
654:                }
655:
656:                boolean paragraphIsLeftToRight(int offset) {
657:
658:                    int lineNumber = fFormatter.lineContaining(offset);
659:                    return fFormatter.lineIsLeftToRight(lineNumber);
660:                }
661:
662:                private void textSizeMightHaveChanged() {
663:
664:                    boolean changed = false;
665:                    final int insetDim = 2 * fInsetAmount;
666:
667:                    int textHeight = fFormatter.maxY() - fFormatter.minY()
668:                            + insetDim;
669:                    if (textHeight != fBounds.height) {
670:                        fBounds.height = textHeight;
671:                        changed = true;
672:                    }
673:
674:                    if (!fFormatter.wrap()) {
675:                        int textWidth = fFormatter.maxX() - fFormatter.minX()
676:                                + insetDim;
677:                        if (textWidth != fBounds.width) {
678:                            fBounds.width = textWidth;
679:                            changed = true;
680:                        }
681:                    }
682:
683:                    if (changed) {
684:                        //System.out.println("Text size changed.  fBounds: " + fBounds);
685:                        calcBoundsRect();
686:                        fHost.documentSizeChanged();
687:                        fHost.scrollToShow(getDocumentBounds());
688:                    }
689:                }
690:
691:                private void doDrawText(Graphics g, Rectangle drawRect,
692:                        boolean selectionVisible, TextOffset selStart,
693:                        TextOffset selEnd, Color hiliteColor) {
694:
695:                    Color oldColor = g.getColor();
696:                    g.setColor(fHost.getHost().getBackground());
697:                    g.fillRect(drawRect.x, drawRect.y, drawRect.width,
698:                            drawRect.height);
699:                    g.setColor(oldColor);
700:
701:                    //            g.clearRect(drawRect.x, drawRect.y, drawRect.width, drawRect.height);
702:
703:                    if (selectionVisible) {
704:                        fFormatter.draw(g, drawRect, fOrigin, selStart, selEnd,
705:                                hiliteColor);
706:                    } else {
707:                        fFormatter.draw(g, drawRect, fOrigin, null, null, null);
708:                    }
709:
710:                    if (selStart != null && selStart.equals(selEnd)
711:                            && selectionVisible) {
712:
713:                        fFormatter.drawCaret(g, selStart, fOrigin,
714:                                STRONG_CARET_COLOR, WEAK_CARET_COLOR);
715:                    }
716:                }
717:
718:                void drawText(Graphics g, Rectangle drawRect,
719:                        boolean selectionVisible, TextOffset selStart,
720:                        TextOffset selEnd, Color hiliteColor) {
721:
722:                    if (g != null) {
723:                        drawRect = drawRect.intersection(fHost.getBounds());
724:                        //System.out.println("drawText:drawRect: " + drawRect);
725:                        g.clipRect(drawRect.x, drawRect.y, drawRect.width,
726:                                drawRect.height);
727:                        if (fNoOffscreenBuffer) {
728:                            doDrawText(g, drawRect, selectionVisible, selStart,
729:                                    selEnd, hiliteColor);
730:                        } else {
731:                            Image offscreenBuffer = fBufferCache.getBuffer(
732:                                    drawRect.width, drawRect.height);
733:                            Graphics offscreenGraphics = offscreenBuffer
734:                                    .getGraphics();
735:                            offscreenGraphics.translate(-drawRect.x,
736:                                    -drawRect.y);
737:
738:                            doDrawText(offscreenGraphics, drawRect,
739:                                    selectionVisible, selStart, selEnd,
740:                                    hiliteColor);
741:
742:                            g.drawImage(offscreenBuffer, drawRect.x,
743:                                    drawRect.y, fHost.fHost);
744:                        }
745:                    }
746:                    textSizeMightHaveChanged();
747:                }
748:
749:                void reformatAndDrawText(int reformatStart, int reformatLength,
750:                        TextOffset selStart, TextOffset selEnd,
751:                        Rectangle additionalUpdateRect, Color hiliteColor) {
752:
753:                    Rectangle visibleBounds = fHost.getBounds();
754:                    Rectangle redrawRect = fFormatter.updateFormat(
755:                            reformatStart, reformatLength, visibleBounds,
756:                            fOrigin);
757:                    //System.out.println("[1] redrawRect: " + redrawRect);
758:
759:                    if (additionalUpdateRect != null) {
760:                        redrawRect.add(additionalUpdateRect);
761:                        //System.out.println("[2] redrawRect: " + redrawRect);
762:                    }
763:
764:                    boolean haveSelection;
765:
766:                    if (selStart != null && selEnd != null) {
767:                        haveSelection = true;
768:                        redrawRect.add(fFormatter.getBoundingRect(selStart,
769:                                selEnd, fOrigin, MFormatter.LOOSE));
770:                        //System.out.println("[3] redrawRect: " + redrawRect);
771:                    } else {
772:                        haveSelection = false;
773:                    }
774:
775:                    drawText(fHost.getGraphics(), redrawRect, haveSelection,
776:                            selStart, selEnd, hiliteColor);
777:                }
778:
779:                private void letBehaviorDraw(Graphics g, Rectangle drawRect) {
780:
781:                    boolean result = false;
782:
783:                    if (fHost.fBehavior != null) {
784:                        result = fHost.fBehavior.paint(g, drawRect);
785:                    }
786:
787:                    if (!result) {
788:                        drawText(g, drawRect, false, null, null, null);
789:                    }
790:                }
791:
792:                void moveBy(int dx, int dy) {
793:
794:                    Rectangle visibleBounds = fHost.getBounds();
795:                    Graphics g = fHost.getGraphics();
796:
797:                    fBounds.x += dx;
798:                    fBounds.y += dy;
799:                    fOrigin.x += dx;
800:                    fOrigin.y += dy;
801:
802:                    Rectangle refreshRect = new Rectangle(visibleBounds);
803:
804:                    if (dx == 0) {
805:                        if (g != null) {
806:                            g.copyArea(visibleBounds.x, visibleBounds.y,
807:                                    visibleBounds.width, visibleBounds.height,
808:                                    dx, dy);
809:                        }
810:                        if (dy < 0) {
811:                            refreshRect.y = visibleBounds.y
812:                                    + visibleBounds.height + dy;
813:                        }
814:                        refreshRect.height = Math.abs(dy);
815:                        //System.out.println("refreshRect=" + refreshRect);
816:                    }
817:
818:                    letBehaviorDraw(g, refreshRect);
819:                }
820:
821:                private Rectangle getInsetBounds() {
822:
823:                    int insetDim = 2 * fInsetAmount;
824:                    return new Rectangle(fBounds.x - fInsetAmount, fBounds.y
825:                            - fInsetAmount, fBounds.width + insetDim,
826:                            fBounds.height + insetDim);
827:                }
828:
829:                void paint(Graphics g) {
830:
831:                    Rectangle hostBounds = fHost.getBounds();
832:                    Rectangle textRefreshRect = hostBounds
833:                            .intersection(getInsetBounds());
834:                    letBehaviorDraw(g, textRefreshRect);
835:                }
836:
837:                Rectangle getCaretRect(TextOffset offset) {
838:
839:                    return fFormatter.getCaretRect(offset, fOrigin);
840:                }
841:
842:                TextOffset pointToTextOffset(TextOffset result, int x, int y,
843:                        TextOffset anchor, boolean infiniteMode) {
844:
845:                    return fFormatter.pointToTextOffset(result, x, y, fOrigin,
846:                            anchor, infiniteMode);
847:                }
848:
849:                Rectangle getScrollableArea() {
850:
851:                    Rectangle area = new Rectangle(fBounds);
852:                    area.x += fInsetAmount - fOrigin.x;
853:                    area.y += fInsetAmount - fOrigin.y;
854:                    return area;
855:                }
856:
857:                /**
858:                 * Doesn't clone so TextComponent needs to be nice.  TextComponent
859:                 * is the only class which can access this anyway.
860:                 */
861:                Rectangle getDocumentBounds() {
862:
863:                    return fBounds;
864:                }
865:
866:                int getDocX() {
867:
868:                    return fOrigin.x - fInsetAmount;
869:                }
870:
871:                int getDocY() {
872:
873:                    return fOrigin.y - fInsetAmount;
874:                }
875:
876:                int lineContaining(TextOffset offset) {
877:
878:                    return fFormatter.lineContaining(offset);
879:                }
880:
881:                int lineRangeLow(int lineNumber) {
882:
883:                    return fFormatter.lineRangeLow(lineNumber);
884:                }
885:
886:                int lineRangeLimit(int lineNumber) {
887:
888:                    return fFormatter.lineRangeLimit(lineNumber);
889:                }
890:
891:                void stopBackgroundFormatting() {
892:
893:                    fFormatter.stopBackgroundFormatting();
894:                }
895:
896:                Rectangle getBoundingRect(TextOffset offset1, TextOffset offset2) {
897:
898:                    Rectangle r = fFormatter.getBoundingRect(offset1, offset2,
899:                            fOrigin, MFormatter.TIGHT);
900:                    //r.width += CARET_SLOP;
901:                    //System.out.println("offset1="+offset1+"; offset2="+offset2);
902:                    //System.out.println("bounds width="+r.width+"; host width="+(fHost.getBounds().width));
903:                    return r;
904:                }
905:
906:                TextOffset findNewInsertionOffset(TextOffset result,
907:                        TextOffset initialOffset, TextOffset previousOffset,
908:                        short direction) {
909:
910:                    return fFormatter.findNewInsertionOffset(result,
911:                            initialOffset, previousOffset, direction);
912:                }
913:            }
914:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.