Source Code Cross Referenced for BaseCaret.java in  » Swing-Library » abeille-forms-designer » org » netbeans » editor » 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 » Swing Library » abeille forms designer » org.netbeans.editor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *                 Sun Public License Notice
0003:         * 
0004:         * The contents of this file are subject to the Sun Public License
0005:         * Version 1.0 (the "License"). You may not use this file except in
0006:         * compliance with the License. A copy of the License is available at
0007:         * http://www.sun.com/
0008:         * 
0009:         * The Original Code is NetBeans. The Initial Developer of the Original
0010:         * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun
0011:         * Microsystems, Inc. All Rights Reserved.
0012:         */
0013:
0014:        package org.netbeans.editor;
0015:
0016:        import java.awt.Color;
0017:        import java.awt.Font;
0018:        import java.awt.Graphics;
0019:        import java.awt.Point;
0020:        import java.awt.Rectangle;
0021:        import java.awt.event.ActionEvent;
0022:        import java.awt.event.ActionListener;
0023:        import java.awt.event.FocusEvent;
0024:        import java.awt.event.FocusListener;
0025:        import java.awt.event.InputEvent;
0026:        import java.awt.event.MouseEvent;
0027:        import java.awt.event.MouseListener;
0028:        import java.awt.event.MouseMotionListener;
0029:        import java.beans.PropertyChangeEvent;
0030:        import java.beans.PropertyChangeListener;
0031:
0032:        import javax.swing.Action;
0033:        import javax.swing.SwingUtilities;
0034:        import javax.swing.Timer;
0035:        import javax.swing.event.ChangeEvent;
0036:        import javax.swing.event.ChangeListener;
0037:        import javax.swing.event.DocumentEvent;
0038:        import javax.swing.event.DocumentListener;
0039:        import javax.swing.event.EventListenerList;
0040:        import javax.swing.text.BadLocationException;
0041:        import javax.swing.text.Caret;
0042:        import javax.swing.text.Document;
0043:        import javax.swing.text.JTextComponent;
0044:
0045:        /**
0046:         * Caret implementation
0047:         * 
0048:         * @author Miloslav Metelka
0049:         * @version 1.00
0050:         */
0051:
0052:        public class BaseCaret extends Rectangle implements  Caret,
0053:                FocusListener, MouseListener, MouseMotionListener,
0054:                PropertyChangeListener, DocumentListener, ActionListener,
0055:                SettingsChangeListener {
0056:
0057:            /** Caret type representing block covering current character */
0058:            public static final String BLOCK_CARET = "block-caret"; // NOI18N
0059:
0060:            /** Default caret type */
0061:            public static final String LINE_CARET = "line-caret"; // NOI18N
0062:
0063:            /** One dot thin line compatible with Swing default caret */
0064:            public static final String THIN_LINE_CARET = "thin-line-caret"; // NOI18N
0065:
0066:            private static final boolean debugCaretFocus = Boolean
0067:                    .getBoolean("netbeans.debug.editor.caret.focus"); // NOI18N
0068:
0069:            /** Component this caret is bound to */
0070:            protected JTextComponent component;
0071:
0072:            /**
0073:             * Position of the caret on the screen. This helps to compute caret position
0074:             * on the next after jump.
0075:             */
0076:            Point magicCaretPosition;
0077:
0078:            /** Draw mark designating the position of the caret. */
0079:            MarkFactory.DrawMark caretMark = new MarkFactory.CaretMark();
0080:
0081:            /** Draw mark that supports caret mark in creating selection */
0082:            MarkFactory.DrawMark selectionMark = new MarkFactory.DrawMark(
0083:                    DrawLayerFactory.CARET_LAYER_NAME, null);
0084:
0085:            /** Is the caret visible */
0086:            boolean visible;
0087:
0088:            /**
0089:             * Caret is visible and the blink is visible. Both must be true in order to
0090:             * show the caret.
0091:             */
0092:            boolean blinkVisible;
0093:
0094:            /** Is the selection currently visible? */
0095:            boolean selectionVisible;
0096:
0097:            /** Listeners */
0098:            protected EventListenerList listenerList = new EventListenerList();
0099:
0100:            /** Timer used for blinking the caret */
0101:            protected Timer flasher;
0102:
0103:            /** Type of the caret */
0104:            String type;
0105:
0106:            /** Is the caret italic for italic fonts */
0107:            boolean italic;
0108:
0109:            private int xPoints[] = new int[4];
0110:            private int yPoints[] = new int[4];
0111:            private Action selectWordAction;
0112:            private Action selectLineAction;
0113:
0114:            /**
0115:             * Change event. Only one instance needed because it has only source
0116:             * property
0117:             */
0118:            protected ChangeEvent changeEvent;
0119:
0120:            private static char emptyDotChar[] = { ' ' };
0121:
0122:            /** Dot array of one character under caret */
0123:            protected char dotChar[] = emptyDotChar;
0124:
0125:            private boolean overwriteMode;
0126:
0127:            /**
0128:             * Remembering document on which caret listens avoids duplicate listener
0129:             * addition to SwingPropertyChangeSupport due to the bug 4200280
0130:             */
0131:            private BaseDocument listenDoc;
0132:
0133:            /** Caret draw graphics */
0134:            CaretDG caretDG = new CaretDG();
0135:
0136:            /**
0137:             * Font of the text underlying the caret. It can be used in caret painting.
0138:             */
0139:            protected Font afterCaretFont;
0140:
0141:            /** Font of the text right before the caret */
0142:            protected Font beforeCaretFont;
0143:
0144:            /**
0145:             * Foreground color of the text underlying the caret. It can be used in
0146:             * caret painting.
0147:             */
0148:            protected Color textForeColor;
0149:
0150:            /**
0151:             * Background color of the text underlying the caret. It can be used in
0152:             * caret painting.
0153:             */
0154:            protected Color textBackColor;
0155:
0156:            private transient FocusListener focusListener;
0157:
0158:            private transient boolean nextPaintUpdate;
0159:            private transient Rectangle nextPaintScrollRect;
0160:            private transient int nextPaintScrollPolicy;
0161:
0162:            static final long serialVersionUID = -9113841520331402768L;
0163:
0164:            public BaseCaret() {
0165:                Settings.addSettingsChangeListener(this );
0166:            }
0167:
0168:            /**
0169:             * Called when settings were changed. The method is called also in
0170:             * constructor, so the code must count with the evt being null.
0171:             */
0172:            public void settingsChange(SettingsChangeEvent evt) {
0173:                if (evt != null
0174:                        && SettingsNames.CARET_BLINK_RATE.equals(evt
0175:                                .getSettingName())) {
0176:                    Object value = evt.getNewValue();
0177:                    if (value instanceof  Integer) {
0178:                        setBlinkRate(((Integer) value).intValue());
0179:                    }
0180:                }
0181:                updateType();
0182:            }
0183:
0184:            void updateType() {
0185:                JTextComponent c = component;
0186:                if (c != null) {
0187:                    Class kitClass = Utilities.getKitClass(c);
0188:                    String newType;
0189:                    boolean newItalic;
0190:                    Color caretColor;
0191:                    if (overwriteMode) {
0192:                        newType = SettingsUtil.getString(kitClass,
0193:                                SettingsNames.CARET_TYPE_OVERWRITE_MODE,
0194:                                LINE_CARET);
0195:                        newItalic = SettingsUtil.getBoolean(kitClass,
0196:                                SettingsNames.CARET_ITALIC_OVERWRITE_MODE,
0197:                                false);
0198:                        caretColor = getColor(
0199:                                kitClass,
0200:                                SettingsNames.CARET_COLOR_OVERWRITE_MODE,
0201:                                SettingsDefaults.defaultCaretColorOvwerwriteMode);
0202:
0203:                    } else { // insert mode
0204:                        newType = SettingsUtil.getString(kitClass,
0205:                                SettingsNames.CARET_TYPE_INSERT_MODE,
0206:                                LINE_CARET);
0207:                        newItalic = SettingsUtil.getBoolean(kitClass,
0208:                                SettingsNames.CARET_ITALIC_INSERT_MODE, false);
0209:                        caretColor = getColor(kitClass,
0210:                                SettingsNames.CARET_COLOR_INSERT_MODE,
0211:                                SettingsDefaults.defaultCaretColorInsertMode);
0212:                    }
0213:
0214:                    this .type = newType;
0215:                    this .italic = newItalic;
0216:                    c.setCaretColor(caretColor);
0217:
0218:                    dispatchUpdate();
0219:                }
0220:            }
0221:
0222:            private static Color getColor(Class kitClass, String settingName,
0223:                    Color defaultValue) {
0224:                Object value = Settings.getValue(kitClass, settingName);
0225:                return (value instanceof  Color) ? (Color) value : defaultValue;
0226:            }
0227:
0228:            /** Called when UI is being installed into JTextComponent */
0229:            public void install(JTextComponent c) {
0230:                component = c;
0231:                component.addPropertyChangeListener(this );
0232:                focusListener = new FocusHandler(this );
0233:                component.addFocusListener(focusListener);
0234:                component.addMouseListener(this );
0235:                component.addMouseMotionListener(this );
0236:
0237:                EditorUI editorUI = Utilities.getEditorUI(component);
0238:                editorUI.addLayer(new DrawLayerFactory.CaretLayer(),
0239:                        DrawLayerFactory.CARET_LAYER_VISIBILITY);
0240:                caretMark.setEditorUI(editorUI);
0241:                selectionMark.setEditorUI(editorUI);
0242:                editorUI.addPropertyChangeListener(this );
0243:
0244:                BaseDocument doc = Utilities.getDocument(c);
0245:                if (doc != null) {
0246:                    modelChanged(null, doc);
0247:                }
0248:
0249:                if (component.hasFocus()) {
0250:                    focusGained(null); // emulate focus gained
0251:                    if (debugCaretFocus) {
0252:                        System.err
0253:                                .println("Component has focus, calling focusGained() on doc="
0254:                                        + component.getDocument().getProperty(
0255:                                                Document.TitleProperty));
0256:                    }
0257:
0258:                }
0259:            }
0260:
0261:            /** Called when UI is being removed from JTextComponent */
0262:            public void deinstall(JTextComponent c) {
0263:                component = null; // invalidate
0264:
0265:                if (flasher != null) {
0266:                    setBlinkRate(0);
0267:                }
0268:
0269:                Utilities.getEditorUI(c).removeLayer(
0270:                        DrawLayerFactory.CARET_LAYER_NAME);
0271:
0272:                c.removeMouseMotionListener(this );
0273:                c.removeMouseListener(this );
0274:                if (focusListener != null) {
0275:                    c.removeFocusListener(focusListener);
0276:                    focusListener = null;
0277:                }
0278:                c.removePropertyChangeListener(this );
0279:
0280:                modelChanged(listenDoc, null);
0281:            }
0282:
0283:            protected void modelChanged(BaseDocument oldDoc, BaseDocument newDoc) {
0284:                // [PENDING] !!! this body looks strange because of the bug 4200280
0285:                if (oldDoc != null && listenDoc == oldDoc) {
0286:                    oldDoc.removeDocumentListener(this );
0287:
0288:                    try {
0289:                        caretMark.remove();
0290:                        selectionMark.remove();
0291:                    } catch (InvalidMarkException e) {
0292:                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
0293:                            e.printStackTrace();
0294:                        }
0295:                    }
0296:
0297:                    listenDoc = null;
0298:                }
0299:
0300:                if (newDoc != null) {
0301:                    if (listenDoc != null) {
0302:                        // deinstall from the listenDoc first
0303:                        modelChanged(listenDoc, null);
0304:                    }
0305:
0306:                    newDoc.addDocumentListener(this );
0307:                    listenDoc = newDoc;
0308:
0309:                    try {
0310:                        Utilities.insertMark(newDoc, caretMark, 0);
0311:                        Utilities.insertMark(newDoc, selectionMark, 0);
0312:                    } catch (InvalidMarkException e) {
0313:                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
0314:                            e.printStackTrace();
0315:                        }
0316:                    } catch (BadLocationException e) {
0317:                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
0318:                            e.printStackTrace();
0319:                        }
0320:                    }
0321:
0322:                    settingsChange(null); // update settings
0323:
0324:                    SwingUtilities.invokeLater(new Runnable() {
0325:                        public void run() {
0326:                            updateType();
0327:                        }
0328:                    });
0329:
0330:                }
0331:            }
0332:
0333:            /** Renders the caret */
0334:            public void paint(Graphics g) {
0335:                if (nextPaintUpdate) { // need to update caret first
0336:                    // running in AWT -> no dispatching
0337:                    nextPaintUpdate = false; // no further updating
0338:                    update(nextPaintScrollRect, nextPaintScrollPolicy);
0339:
0340:                    // fix for issue #13049
0341:                    nextPaintScrollRect = null;
0342:
0343:                }
0344:
0345:                if (visible && blinkVisible) {
0346:                    paintCustomCaret(g);
0347:                }
0348:            }
0349:
0350:            protected void paintCustomCaret(Graphics g) {
0351:                JTextComponent c = component;
0352:                if (c != null) {
0353:                    EditorUI editorUI = Utilities.getEditorUI(c);
0354:                    if (THIN_LINE_CARET.equals(type)) { // thin line caret
0355:                        g.setColor(c.getCaretColor());
0356:                        int upperX = x;
0357:                        if (beforeCaretFont != null
0358:                                && beforeCaretFont.isItalic() && italic) {
0359:                            upperX += Math
0360:                                    .tan(beforeCaretFont.getItalicAngle())
0361:                                    * height;
0362:                        }
0363:                        g.drawLine((int) upperX, y, x, (y + height - 1));
0364:
0365:                    } else if (BLOCK_CARET.equals(type)) { // block caret
0366:                        g.setColor(c.getCaretColor());
0367:                        g.setFont(afterCaretFont);
0368:                        if (afterCaretFont.isItalic() && italic) { // paint italic
0369:                            // caret
0370:                            int upperX = (int) (x + Math.tan(afterCaretFont
0371:                                    .getItalicAngle())
0372:                                    * height);
0373:                            xPoints[0] = upperX;
0374:                            yPoints[0] = y;
0375:                            xPoints[1] = upperX + width;
0376:                            yPoints[1] = y;
0377:                            xPoints[2] = x + width;
0378:                            yPoints[2] = y + height - 1;
0379:                            xPoints[3] = x;
0380:                            yPoints[3] = y + height - 1;
0381:                            g.fillPolygon(xPoints, yPoints, 4);
0382:
0383:                        } else { // paint non-italic caret
0384:                            g.fillRect(x, y, width, height);
0385:                        }
0386:
0387:                        if (!Character.isWhitespace(dotChar[0])) {
0388:                            g.setColor(Color.white);
0389:                            int ascent = FontMetricsCache.getFontMetrics(
0390:                                    afterCaretFont, c).getAscent();
0391:                            g.drawChars(dotChar, 0, 1, x, y
0392:                                    + editorUI.getLineAscent());
0393:                        }
0394:
0395:                    } else { // two dot line caret
0396:                        g.setColor(c.getCaretColor());
0397:                        int blkWidth = 2;
0398:                        if (beforeCaretFont != null
0399:                                && beforeCaretFont.isItalic() && italic) {
0400:                            int upperX = (int) (x + Math.tan(beforeCaretFont
0401:                                    .getItalicAngle())
0402:                                    * height);
0403:                            xPoints[0] = upperX;
0404:                            yPoints[0] = y;
0405:                            xPoints[1] = upperX + blkWidth;
0406:                            yPoints[1] = y;
0407:                            xPoints[2] = x + blkWidth;
0408:                            yPoints[2] = y + height - 1;
0409:                            xPoints[3] = x;
0410:                            yPoints[3] = y + height - 1;
0411:                            g.fillPolygon(xPoints, yPoints, 4);
0412:                        } else { // paint non-italic caret
0413:                            g.fillRect(x, y, blkWidth, height - 1);
0414:                        }
0415:                    }
0416:                }
0417:            }
0418:
0419:            /** Update the caret's visual position */
0420:            void dispatchUpdate() {
0421:                dispatchUpdate(null, EditorUI.SCROLL_MOVE);
0422:            }
0423:
0424:            void dispatchUpdate(final Rectangle scrollRect,
0425:                    final int scrollPolicy) {
0426:                JTextComponent c = component;
0427:                EditorUI editorUI = Utilities.getEditorUI(c);
0428:                if (!editorUI.isFontsInited()) { // fonts not yet initialized
0429:                    if (scrollRect != null) { // do not hide the "really" scrolling
0430:                        // requests
0431:                        nextPaintScrollRect = scrollRect;
0432:                    }
0433:                    nextPaintScrollPolicy = scrollPolicy;
0434:                    nextPaintUpdate = true;
0435:                    return;
0436:                }
0437:
0438:                /*
0439:                 * part of fix of #18860 - Using runInEventDispatchThread() in AWT
0440:                 * thread means that the code is executed immediately which can lead to
0441:                 * problems once the insert/remove in document is performed because the
0442:                 * update() uses views to find out the visual position and if the views
0443:                 * doc listener is added AFTER the caret's listener then the views are
0444:                 * not updated yet. Using SwingUtilities.invokeLater() should solve the
0445:                 * problem although the view extent could flip once the extent would be
0446:                 * explicitely scrolled to area that does not cover the caret's
0447:                 * rectangle. It needs to be tested so that it does not happen.
0448:                 */
0449:                // Utilities.runInEventDispatchThread(
0450:                SwingUtilities.invokeLater(new Runnable() {
0451:                    public void run() {
0452:                        JTextComponent c2 = component;
0453:                        if (c2 != null) {
0454:                            BaseDocument doc = Utilities.getDocument(c2);
0455:                            if (doc != null) {
0456:                                doc.readLock();
0457:                                try {
0458:                                    update(scrollRect, scrollPolicy);
0459:                                } finally {
0460:                                    doc.readUnlock();
0461:                                }
0462:                            }
0463:                        }
0464:
0465:                    }
0466:                });
0467:            }
0468:
0469:            /**
0470:             * Update the caret. The document is read-locked while calling this method.
0471:             * 
0472:             * @param scrollRect
0473:             *            rectangle that should be visible after the updating of the
0474:             *            caret. It can be null to do no scrolling (only update caret)
0475:             *            or it can be caret rectangle to update the caret and make it
0476:             *            visible or some other rectangle to guarantee that the
0477:             *            rectangle will be visible.
0478:             * @param scrollPolicy
0479:             *            scrolling policy as defined in EditorUI. It has no meaning if
0480:             *            <code>scrollRect</code> is null.
0481:             */
0482:            protected void update(Rectangle scrollRect, int scrollPolicy) {
0483:                JTextComponent c = component;
0484:                if (c != null) {
0485:                    BaseTextUI ui = (BaseTextUI) c.getUI();
0486:                    EditorUI editorUI = ui.getEditorUI();
0487:                    BaseDocument doc = Utilities.getDocument(c);
0488:                    if (doc != null) {
0489:                        Rectangle oldCaretRect = new Rectangle(this );
0490:                        if (italic) { // caret is italic - add char height to the
0491:                            // width of the rect
0492:                            oldCaretRect.width += oldCaretRect.height;
0493:                        }
0494:
0495:                        int dot = getDot();
0496:                        try {
0497:                            ui.modelToViewDG(dot, caretDG);
0498:                        } catch (BadLocationException e) {
0499:                            if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
0500:                                e.printStackTrace();
0501:                            }
0502:                        }
0503:                        resetBlink();
0504:
0505:                        if (scrollRect == null
0506:                                || !editorUI.scrollRectToVisibleFragile(
0507:                                        scrollRect, scrollPolicy)) {
0508:                            oldCaretRect.add(this ); // adds the NEW caret rect -
0509:                            // important!
0510:                            c.repaint(oldCaretRect);
0511:                        }
0512:                    }
0513:                }
0514:            }
0515:
0516:            /**
0517:             * Redefine to Object.equals() to prevent defaulting to Rectangle.equals()
0518:             * which would cause incorrect firing
0519:             */
0520:            public boolean equals(Object o) {
0521:                return (this  == o);
0522:            }
0523:
0524:            /** Adds listener to track when caret position was changed */
0525:            public void addChangeListener(ChangeListener l) {
0526:                listenerList.add(ChangeListener.class, l);
0527:            }
0528:
0529:            /** Removes listeners to caret position changes */
0530:            public void removeChangeListener(ChangeListener l) {
0531:                listenerList.remove(ChangeListener.class, l);
0532:            }
0533:
0534:            /** Notifies listeners that caret position has changed */
0535:            protected void fireStateChanged() {
0536:                Object listeners[] = listenerList.getListenerList();
0537:                for (int i = listeners.length - 2; i >= 0; i -= 2) {
0538:                    if (listeners[i] == ChangeListener.class) {
0539:                        if (changeEvent == null) {
0540:                            changeEvent = new ChangeEvent(this );
0541:                        }
0542:                        ((ChangeListener) listeners[i + 1])
0543:                                .stateChanged(changeEvent);
0544:                    }
0545:                }
0546:            }
0547:
0548:            /** Is the caret currently visible */
0549:            public final boolean isVisible() {
0550:                return visible;
0551:            }
0552:
0553:            protected void setVisibleImpl(boolean v) {
0554:                synchronized (this ) {
0555:                    Timer t = flasher;
0556:                    if (t != null) {
0557:                        if (visible) {
0558:                            t.stop();
0559:                        }
0560:                        if (v) {
0561:                            t.start();
0562:                        } else {
0563:                            t.stop();
0564:                        }
0565:                    }
0566:                    visible = v;
0567:                }
0568:                JTextComponent c = component;
0569:                if (c != null) {
0570:                    Rectangle repaintRect = this ;
0571:                    if (italic) {
0572:                        repaintRect = new Rectangle(this );
0573:                        repaintRect.width += repaintRect.height;
0574:                    }
0575:                    c.repaint(repaintRect);
0576:                }
0577:            }
0578:
0579:            synchronized void resetBlink() {
0580:                Timer t = flasher;
0581:                if (t != null) {
0582:                    t.stop();
0583:                    blinkVisible = true;
0584:                    if (isVisible()) {
0585:                        t.start();
0586:                    }
0587:                }
0588:            }
0589:
0590:            /** Sets the caret visibility */
0591:            public void setVisible(final boolean v) {
0592:                SwingUtilities.invokeLater(new Runnable() {
0593:                    public void run() {
0594:                        setVisibleImpl(v);
0595:                    }
0596:                });
0597:            }
0598:
0599:            /** Is the selection visible? */
0600:            public final boolean isSelectionVisible() {
0601:                return selectionVisible;
0602:            }
0603:
0604:            /** Sets the selection visibility */
0605:            public void setSelectionVisible(boolean v) {
0606:                if (selectionVisible == v) {
0607:                    return;
0608:                }
0609:                JTextComponent c = component;
0610:                if (c != null) {
0611:                    selectionVisible = v;
0612:                    if (selectionVisible) {
0613:                        int caretPos = getDot();
0614:                        int selPos = getMark();
0615:                        boolean selMarkFirst = (selPos < caretPos);
0616:                        selectionMark.activateLayer = selMarkFirst;
0617:                        caretMark.activateLayer = !selMarkFirst
0618:                                && !(selPos == caretPos);
0619:                    } else { // make selection invisible
0620:                        caretMark.activateLayer = false;
0621:                        selectionMark.activateLayer = false;
0622:                    }
0623:
0624:                    // repaint the block
0625:                    BaseTextUI ui = (BaseTextUI) c.getUI();
0626:                    try {
0627:                        ui.getEditorUI().repaintBlock(caretMark.getOffset(),
0628:                                selectionMark.getOffset());
0629:                    } catch (BadLocationException e) {
0630:                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
0631:                            e.printStackTrace();
0632:                        }
0633:                    } catch (InvalidMarkException e) {
0634:                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
0635:                            e.printStackTrace();
0636:                        }
0637:                    }
0638:
0639:                }
0640:            }
0641:
0642:            /**
0643:             * Saves the current caret position. This is used when caret up or down
0644:             * actions occur, moving between lines that have uneven end positions.
0645:             * 
0646:             * @param p
0647:             *            the Point to use for the saved position
0648:             */
0649:            public void setMagicCaretPosition(Point p) {
0650:                magicCaretPosition = p;
0651:            }
0652:
0653:            /** Get position used to mark begining of the selected block */
0654:            public final Point getMagicCaretPosition() {
0655:                return magicCaretPosition;
0656:            }
0657:
0658:            /**
0659:             * Sets the caret blink rate.
0660:             * 
0661:             * @param rate
0662:             *            blink rate in milliseconds, 0 means no blink
0663:             */
0664:            public synchronized void setBlinkRate(int rate) {
0665:                if (flasher == null && rate > 0) {
0666:                    flasher = new Timer(rate, new WeakTimerListener(this ));
0667:                }
0668:                if (flasher != null) {
0669:                    if (rate > 0) {
0670:                        if (flasher.getDelay() != rate) {
0671:                            flasher.setDelay(rate);
0672:                        }
0673:                    } else { // zero rate - don't blink
0674:                        flasher.stop();
0675:                        flasher.removeActionListener(this );
0676:                        flasher = null;
0677:                    }
0678:                }
0679:            }
0680:
0681:            /** Returns blink rate of the caret or 0 if caret doesn't blink */
0682:            public synchronized int getBlinkRate() {
0683:                return (flasher != null) ? flasher.getDelay() : 0;
0684:            }
0685:
0686:            /** Gets the current position of the caret */
0687:            public int getDot() {
0688:                if (component != null) {
0689:                    try {
0690:                        return caretMark.getOffset();
0691:                    } catch (InvalidMarkException e) {
0692:                    }
0693:                }
0694:                return 0;
0695:            }
0696:
0697:            /**
0698:             * Gets the current position of the selection mark. If there's a selection
0699:             * this position will be different from the caret position.
0700:             */
0701:            public int getMark() {
0702:                if (component != null) {
0703:                    if (selectionVisible) {
0704:                        try {
0705:                            return selectionMark.getOffset();
0706:                        } catch (InvalidMarkException e) {
0707:                        }
0708:                    } else { // selection not visible
0709:                        return getDot(); // must return same position as dot
0710:                    }
0711:                }
0712:                return 0;
0713:            }
0714:
0715:            public void setDot(int offset) {
0716:                setDot(offset, this , EditorUI.SCROLL_DEFAULT);
0717:            }
0718:
0719:            /**
0720:             * Sets the caret position to some position. This causes removal of the
0721:             * active selection.
0722:             */
0723:            public void setDot(int offset, Rectangle scrollRect,
0724:                    int scrollPolicy) {
0725:                JTextComponent c = component;
0726:                if (c != null) {
0727:                    setSelectionVisible(false);
0728:                    BaseDocument doc = (BaseDocument) c.getDocument();
0729:                    if (doc != null) {
0730:                        try {
0731:                            Utilities.moveMark(doc, caretMark, offset);
0732:                        } catch (BadLocationException e) {
0733:                            // setting the caret to wrong position leaves it at current
0734:                            // position
0735:                        } catch (InvalidMarkException e) {
0736:                            // Caret not installed or inside the initial-read
0737:                        }
0738:                    }
0739:                    fireStateChanged();
0740:                    dispatchUpdate(scrollRect, scrollPolicy);
0741:                }
0742:            }
0743:
0744:            public void moveDot(int offset) {
0745:                moveDot(offset, this , EditorUI.SCROLL_MOVE);
0746:            }
0747:
0748:            /** Makes selection by moving dot but leaving mark */
0749:            public void moveDot(int offset, Rectangle scrollRect,
0750:                    int scrollPolicy) {
0751:                JTextComponent c = component;
0752:                if (c != null) {
0753:                    BaseDocument doc = (BaseDocument) c.getDocument();
0754:                    try {
0755:                        int oldCaretPos = getDot();
0756:                        if (offset == oldCaretPos) { // no change
0757:                            return;
0758:                        }
0759:                        int selPos; // current position of selection mark
0760:
0761:                        if (selectionVisible) {
0762:                            selPos = selectionMark.getOffset();
0763:                        } else {
0764:                            Utilities.moveMark(doc, selectionMark, oldCaretPos);
0765:                            selPos = oldCaretPos;
0766:                        }
0767:
0768:                        Utilities.moveMark(doc, caretMark, offset);
0769:                        if (selectionVisible) { // selection already visible
0770:                            boolean selMarkFirst = (selPos < offset);
0771:                            selectionMark.activateLayer = selMarkFirst;
0772:                            caretMark.activateLayer = !selMarkFirst
0773:                                    && !(selPos == offset);
0774:                            Utilities.getEditorUI(c).repaintBlock(oldCaretPos,
0775:                                    offset);
0776:                            if (selPos == offset) { // same positions -> invisible
0777:                                // selection
0778:                                setSelectionVisible(false);
0779:                            }
0780:
0781:                        } else { // selection not yet visible
0782:                            setSelectionVisible(true);
0783:                        }
0784:                    } catch (BadLocationException e) {
0785:                        // position is incorrect
0786:                    } catch (InvalidMarkException e) {
0787:                        if (Boolean.getBoolean("netbeans.debug.exceptions")) { // NOI18N
0788:                            e.printStackTrace();
0789:                        }
0790:                    }
0791:                    fireStateChanged();
0792:                    dispatchUpdate(scrollRect, scrollPolicy);
0793:                }
0794:            }
0795:
0796:            // DocumentListener methods
0797:            public void insertUpdate(DocumentEvent evt) {
0798:                JTextComponent c = component;
0799:                if (c != null) {
0800:                    BaseDocument doc = (BaseDocument) component.getDocument();
0801:                    BaseDocumentEvent bevt = (BaseDocumentEvent) evt;
0802:                    if ((bevt.isInUndo() || bevt.isInRedo())
0803:                            && component == Utilities.getLastActiveComponent()) {
0804:                        // in undo mode and current component
0805:                        setDot(evt.getOffset() + evt.getLength());
0806:                    } else {
0807:                        fireStateChanged();
0808:                        if (evt.getLength() == 0) {
0809:                            updateType();
0810:                            setVisible(false);
0811:                            setVisible(c.isEnabled() && c.hasFocus());
0812:                        }
0813:
0814:                        // Scroll to caret only for component with focus
0815:                        dispatchUpdate(c.hasFocus() ? this  : null,
0816:                                EditorUI.SCROLL_MOVE);
0817:                    }
0818:                }
0819:            }
0820:
0821:            public void removeUpdate(DocumentEvent evt) {
0822:                JTextComponent c = component;
0823:                if (c != null) {
0824:                    BaseDocument doc = (BaseDocument) c.getDocument();
0825:                    // make selection invisible if removal shrinked block to zero size
0826:                    if (selectionVisible && (getDot() == getMark())) {
0827:                        setSelectionVisible(false);
0828:                    }
0829:
0830:                    BaseDocumentEvent bevt = (BaseDocumentEvent) evt;
0831:                    if ((bevt.isInUndo() || bevt.isInRedo())
0832:                            && c == Utilities.getLastActiveComponent()) {
0833:                        // in undo mode and current component
0834:                        setDot(evt.getOffset());
0835:                    } else {
0836:                        fireStateChanged();
0837:                        // Scroll to caret only for component with focus
0838:                        dispatchUpdate(c.hasFocus() ? this  : null,
0839:                                EditorUI.SCROLL_MOVE);
0840:                    }
0841:                }
0842:            }
0843:
0844:            public void changedUpdate(DocumentEvent evt) {
0845:                dispatchUpdate();
0846:            }
0847:
0848:            // FocusListener methods
0849:            public void focusGained(FocusEvent evt) {
0850:                if (debugCaretFocus) {
0851:                    System.err.println("BaseCaret.focusGained() in doc="
0852:                            + component.getDocument().getProperty(
0853:                                    Document.TitleProperty));
0854:                }
0855:
0856:                JTextComponent c = component;
0857:                if (c != null) {
0858:                    updateType();
0859:                    setVisible(c.isEnabled()); // invisible caret if disabled
0860:                }
0861:            }
0862:
0863:            public void focusLost(FocusEvent evt) {
0864:                if (debugCaretFocus) {
0865:                    System.err.println("BaseCaret.focusLost() in doc="
0866:                            + component.getDocument().getProperty(
0867:                                    Document.TitleProperty));
0868:                }
0869:
0870:                setVisible(false);
0871:            }
0872:
0873:            // MouseListener methods
0874:            public void mouseClicked(MouseEvent evt) {
0875:                JTextComponent c = component;
0876:                if (c != null) {
0877:                    if (SwingUtilities.isLeftMouseButton(evt)) {
0878:                        if (evt.getClickCount() == 2) {
0879:                            if (selectWordAction == null) {
0880:                                BaseTextUI ui = (BaseTextUI) c.getUI();
0881:                                selectWordAction = ((BaseKit) ui
0882:                                        .getEditorKit(c))
0883:                                        .getActionByName(BaseKit.selectWordAction);
0884:                            }
0885:                            selectWordAction.actionPerformed(null);
0886:                        } else if (evt.getClickCount() == 3) {
0887:                            if (selectLineAction == null) {
0888:                                BaseTextUI ui = (BaseTextUI) c.getUI();
0889:                                selectLineAction = ((BaseKit) ui
0890:                                        .getEditorKit(c))
0891:                                        .getActionByName(BaseKit.selectLineAction);
0892:                            }
0893:                            selectLineAction.actionPerformed(null);
0894:                        }
0895:                    }
0896:                }
0897:            }
0898:
0899:            public void mousePressed(MouseEvent evt) {
0900:                JTextComponent c = component;
0901:                if (c != null) {
0902:                    Utilities.getEditorUI(c).getWordMatch().clear(); // [PENDING]
0903:                    // should be
0904:                    // done cleanly
0905:
0906:                    // Position the cursor at the appropriate place in the document
0907:                    if ((SwingUtilities.isLeftMouseButton(evt) && (evt
0908:                            .getModifiers() & (InputEvent.META_MASK | InputEvent.ALT_MASK)) == 0)
0909:                            || !isSelectionVisible()) {
0910:                        int offset = ((BaseTextUI) c.getUI()).viewToModel(c,
0911:                                evt.getX(), evt.getY());
0912:                        if (offset >= 0) {
0913:                            if ((evt.getModifiers() & InputEvent.SHIFT_MASK) != 0) {
0914:                                moveDot(offset);
0915:                            } else {
0916:                                setDot(offset);
0917:                            }
0918:                            setMagicCaretPosition(null);
0919:                        }
0920:                        if (c.isEnabled()) {
0921:                            c.requestFocus();
0922:                        }
0923:                    }
0924:                }
0925:            }
0926:
0927:            public void mouseReleased(MouseEvent evt) {
0928:            }
0929:
0930:            public void mouseEntered(MouseEvent evt) {
0931:            }
0932:
0933:            public void mouseExited(MouseEvent evt) {
0934:            }
0935:
0936:            // MouseMotionListener methods
0937:            public void mouseDragged(MouseEvent evt) {
0938:                JTextComponent c = component;
0939:                if (SwingUtilities.isLeftMouseButton(evt)) {
0940:                    if (c != null) {
0941:                        int offset = ((BaseTextUI) c.getUI()).viewToModel(c,
0942:                                evt.getX(), evt.getY());
0943:                        // fix for #15204
0944:                        if (offset == -1)
0945:                            offset = 0;
0946:                        moveDot(offset);
0947:                    }
0948:                }
0949:            }
0950:
0951:            public void mouseMoved(MouseEvent evt) {
0952:            }
0953:
0954:            // PropertyChangeListener methods
0955:            public void propertyChange(PropertyChangeEvent evt) {
0956:                String propName = evt.getPropertyName();
0957:                if ("document".equals(propName)) {
0958:                    BaseDocument oldDoc = (evt.getOldValue() instanceof  BaseDocument) ? (BaseDocument) evt
0959:                            .getOldValue()
0960:                            : null;
0961:                    BaseDocument newDoc = (evt.getNewValue() instanceof  BaseDocument) ? (BaseDocument) evt
0962:                            .getNewValue()
0963:                            : null;
0964:                    modelChanged(oldDoc, newDoc);
0965:                } else if (EditorUI.OVERWRITE_MODE_PROPERTY.equals(propName)) {
0966:                    Boolean b = (Boolean) evt.getNewValue();
0967:                    overwriteMode = (b != null) ? b.booleanValue() : false;
0968:                    updateType();
0969:                }
0970:            }
0971:
0972:            // ActionListener methods
0973:            /** Fired when blink timer fires */
0974:            public void actionPerformed(ActionEvent evt) {
0975:                JTextComponent c = component;
0976:                if (c != null) {
0977:                    blinkVisible = !blinkVisible;
0978:                    Rectangle repaintRect = this ;
0979:                    if (italic) {
0980:                        repaintRect = new Rectangle(this );
0981:                        repaintRect.width += repaintRect.height;
0982:                    }
0983:                    c.repaint(repaintRect);
0984:                }
0985:            }
0986:
0987:            /**
0988:             * Caret draw graphics used to update the caret position and the character
0989:             * the caret sits on.
0990:             */
0991:            final class CaretDG extends DrawGraphics.SimpleDG {
0992:
0993:                Font previousFont;
0994:
0995:                public void setFont(Font font) {
0996:                    previousFont = getFont(); // get the current font before change
0997:                    super .setFont(font);
0998:                }
0999:
1000:                public boolean targetOffsetReached(int offset, char ch, int x,
1001:                        int charWidth, DrawContext ctx) {
1002:
1003:                    JTextComponent c = BaseCaret.this .component;
1004:                    if (c != null) {
1005:                        BaseCaret.this .beforeCaretFont = (offset == ctx
1006:                                .getFragmentOffset()) ? previousFont : ctx
1007:                                .getFont();
1008:                        BaseCaret.this .afterCaretFont = ctx.getFont();
1009:
1010:                        BaseCaret.this .x = x;
1011:                        BaseCaret.this .y = this .getY();
1012:                        BaseCaret.this .width = charWidth;
1013:                        BaseCaret.this .height = Utilities.getEditorUI(c)
1014:                                .getLineHeight();
1015:                        BaseCaret.this .textForeColor = ctx.getForeColor();
1016:                        BaseCaret.this .textBackColor = ctx.getBackColor();
1017:                        BaseCaret.this .dotChar[0] = ch;
1018:                    }
1019:                    return false;
1020:                }
1021:
1022:            }
1023:
1024:            private static class FocusHandler implements  FocusListener {
1025:                private transient FocusListener fl;
1026:
1027:                FocusHandler(FocusListener fl) {
1028:                    this .fl = fl;
1029:                }
1030:
1031:                public void focusGained(FocusEvent e) {
1032:                    fl.focusGained(e);
1033:                }
1034:
1035:                public void focusLost(FocusEvent e) {
1036:                    fl.focusLost(e);
1037:                }
1038:            }
1039:
1040:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.