Source Code Cross Referenced for ToolTipSupport.java in  » IDE-Netbeans » editor » org » netbeans » editor » ext » 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 » IDE Netbeans » editor » org.netbeans.editor.ext 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:         *
004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:         *
006:         * The contents of this file are subject to the terms of either the GNU
007:         * General Public License Version 2 only ("GPL") or the Common
008:         * Development and Distribution License("CDDL") (collectively, the
009:         * "License"). You may not use this file except in compliance with the
010:         * License. You can obtain a copy of the License at
011:         * http://www.netbeans.org/cddl-gplv2.html
012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013:         * specific language governing permissions and limitations under the
014:         * License.  When distributing the software, include this License Header
015:         * Notice in each file and include the License file at
016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
017:         * particular file as subject to the "Classpath" exception as provided
018:         * by Sun in the GPL Version 2 section of the License file that
019:         * accompanied this code. If applicable, add the following below the
020:         * License Header, with the fields enclosed by brackets [] replaced by
021:         * your own identifying information:
022:         * "Portions Copyrighted [year] [name of copyright owner]"
023:         *
024:         * Contributor(s):
025:         *
026:         * The Original Software is NetBeans. The Initial Developer of the Original
027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028:         * Microsystems, Inc. All Rights Reserved.
029:         *
030:         * If you wish your version of this file to be governed by only the CDDL
031:         * or only the GPL Version 2, indicate your decision by adding
032:         * "[Contributor] elects to include this software in this distribution
033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
034:         * single choice of license, a recipient has the option to distribute
035:         * your version of this file under either the CDDL, the GPL Version 2 or
036:         * to extend the choice of license to its licensees as provided above.
037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
038:         * Version 2 license, then the option applies only if the new code is
039:         * made subject to such option by the copyright holder.
040:         */
041:
042:        package org.netbeans.editor.ext;
043:
044:        import java.awt.Dimension;
045:        import java.awt.Point;
046:        import java.awt.Rectangle;
047:        import java.awt.Font;
048:        import java.awt.Color;
049:        import java.awt.event.ActionListener;
050:        import java.awt.event.ActionEvent;
051:        import java.awt.event.MouseMotionListener;
052:        import java.awt.event.MouseAdapter;
053:        import java.awt.event.MouseEvent;
054:        import java.awt.event.FocusListener;
055:        import java.awt.event.FocusEvent;
056:        import java.beans.PropertyChangeListener;
057:        import java.beans.PropertyChangeEvent;
058:        import java.beans.PropertyChangeSupport;
059:        import javax.swing.JComponent;
060:        import javax.swing.Timer;
061:        import javax.swing.Action;
062:        import javax.swing.ActionMap;
063:        import javax.swing.BorderFactory;
064:        import javax.swing.JEditorPane;
065:        import javax.swing.UIManager;
066:        import javax.swing.text.JTextComponent;
067:        import javax.swing.text.BadLocationException;
068:        import org.netbeans.editor.SettingsChangeListener;
069:        import org.netbeans.editor.SettingsChangeEvent;
070:        import org.netbeans.editor.Settings;
071:        import org.netbeans.editor.Utilities;
072:        import org.netbeans.editor.BaseKit;
073:        import org.netbeans.editor.BaseTextUI;
074:        import org.netbeans.editor.BaseDocument;
075:        import org.netbeans.editor.WeakTimerListener;
076:        import org.netbeans.editor.PopupManager;
077:        import javax.swing.JTextArea;
078:        import org.netbeans.editor.GlyphGutter;
079:        import javax.swing.JViewport;
080:        import javax.swing.text.Document;
081:        import javax.swing.text.Element;
082:
083:        /**
084:         * Support for editor tooltips. Once the user stops moving the mouse
085:         * for the {@link #INITIAL_DELAY} milliseconds the enterTimer fires
086:         * and the {@link #updateToolTip()} method is called which searches
087:         * for the action named {@link ExtKit#buildToolTipAction} and if found
088:         * it executes it. The tooltips can be displayed by either calling
089:         * {@link #setToolTipText(java.lang.String)}
090:         * or {@link #setToolTip(javax.swing.JComponent)}.<BR>
091:         * However only one of the above ways should be used
092:         * not a combination of both because in such case
093:         * the text could be propagated in the previously set
094:         * custom tooltip component. 
095:         *
096:         * @author Miloslav Metelka
097:         * @version 1.00
098:         */
099:
100:        public class ToolTipSupport extends MouseAdapter implements 
101:                MouseMotionListener, ActionListener, PropertyChangeListener,
102:                SettingsChangeListener, FocusListener {
103:
104:            /** Property for the tooltip component change */
105:            public static final String PROP_TOOL_TIP = "toolTip"; // NOI18N
106:
107:            /** Property for the tooltip text change */
108:            public static final String PROP_TOOL_TIP_TEXT = "toolTipText"; // NOI18N
109:
110:            /** Property for the visibility status change. */
111:            public static final String PROP_STATUS = "status"; // NOI18N
112:
113:            /** Property for the enabled flag change */
114:            public static final String PROP_ENABLED = "enabled"; // NOI18N
115:
116:            /** Property for the initial delay change */
117:            public static final String PROP_INITIAL_DELAY = "initialDelay"; // NOI18N
118:
119:            /** Property for the dismiss delay change */
120:            public static final String PROP_DISMISS_DELAY = "dismissDelay"; // NOI18N
121:
122:            private static final String UI_PREFIX = "ToolTip"; // NOI18N
123:
124:            /** Initial delay before the tooltip is shown in milliseconds. */
125:            public static final int INITIAL_DELAY = 200;
126:
127:            /** Delay after which the tooltip will be hidden automatically
128:             * in milliseconds.
129:             */
130:            public static final int DISMISS_DELAY = 60000;
131:
132:            /** Status indicating that  the tooltip is not showing on the screen. */
133:            public static final int STATUS_HIDDEN = 0;
134:            /** Status indicating that  the tooltip is not showing on the screen
135:             * but once either the {@link #setToolTipText(java.lang.String)}
136:             * or {@link #setToolTip(javax.swing.JComponent)} gets called
137:             * the tooltip will become visible.
138:             */
139:            public static final int STATUS_VISIBILITY_ENABLED = 1;
140:            /** Status indicating that the tooltip is visible
141:             * because {@link #setToolTipText(java.lang.String)}
142:             * was called.
143:             */
144:            public static final int STATUS_TEXT_VISIBLE = 2;
145:            /** Status indicating that the tooltip is visible
146:             * because {@link #setToolTip(javax.swing.JComponent)}
147:             * was called.
148:             */
149:            public static final int STATUS_COMPONENT_VISIBLE = 3;
150:
151:            /** Extra height added to the rectangle of modelToView() for mouse
152:             * cursor coordinates.
153:             */
154:            private static final int MOUSE_EXTRA_HEIGHT = 5;
155:
156:            private static final String HTML_PREFIX_LOWERCASE = "<html"; //NOI18N
157:            private static final String HTML_PREFIX_UPPERCASE = "<HTML"; //NOI18N
158:
159:            private ExtEditorUI extEditorUI;
160:
161:            private JComponent toolTip;
162:
163:            private String toolTipText;
164:
165:            private Timer enterTimer;
166:
167:            private Timer exitTimer;
168:
169:            private boolean enabled;
170:
171:            /** Status of the tooltip visibility. */
172:            private int status;
173:
174:            private MouseEvent lastMouseEvent;
175:
176:            private PropertyChangeSupport pcs;
177:
178:            private PopupManager.HorizontalBounds horizontalBounds = PopupManager.ViewPortBounds;
179:            private PopupManager.Placement placement = PopupManager.AbovePreferred;
180:
181:            private int verticalAdjustment;
182:            private int horizontalAdjustment;
183:
184:            private boolean glyphListenerAdded = false;
185:
186:            /** Construct new support for tooltips.
187:             */
188:            public ToolTipSupport(ExtEditorUI extEditorUI) {
189:                this .extEditorUI = extEditorUI;
190:
191:                enterTimer = new Timer(INITIAL_DELAY, new WeakTimerListener(
192:                        this ));
193:                enterTimer.setRepeats(false);
194:                exitTimer = new Timer(DISMISS_DELAY,
195:                        new WeakTimerListener(this ));
196:                exitTimer.setRepeats(false);
197:
198:                Settings.addSettingsChangeListener(this );
199:                extEditorUI.addPropertyChangeListener(this );
200:
201:                setEnabled(true);
202:            }
203:
204:            /** @return the component that either contains the tooltip
205:             * or is responsible for displaying of text tooltips.
206:             */
207:            public final JComponent getToolTip() {
208:                if (toolTip == null) {
209:                    setToolTip(createDefaultToolTip());
210:                }
211:
212:                return toolTip;
213:            }
214:
215:            /** Set the tooltip component.
216:             * It can be called either to set the custom component
217:             * that will display the text tooltips or to display
218:             * the generic component with the tooltip after
219:             * the tooltip timer has fired.
220:             * @param toolTip component that either contains the tooltip
221:             *  or that will display a text tooltip.
222:             */
223:            public void setToolTip(JComponent toolTip) {
224:                setToolTip(toolTip, PopupManager.ViewPortBounds,
225:                        PopupManager.AbovePreferred);
226:            }
227:
228:            public void setToolTip(JComponent toolTip,
229:                    PopupManager.HorizontalBounds horizontalBounds,
230:                    PopupManager.Placement placement) {
231:                setToolTip(toolTip, PopupManager.ViewPortBounds,
232:                        PopupManager.AbovePreferred, 0, 0);
233:            }
234:
235:            public void setToolTip(JComponent toolTip,
236:                    PopupManager.HorizontalBounds horizontalBounds,
237:                    PopupManager.Placement placement, int horizontalAdjustment,
238:                    int verticalAdjustment) {
239:                JComponent oldToolTip = this .toolTip;
240:                this .toolTip = toolTip;
241:                this .horizontalBounds = horizontalBounds;
242:                this .placement = placement;
243:                this .horizontalAdjustment = horizontalAdjustment;
244:                this .verticalAdjustment = verticalAdjustment;
245:
246:                if (status >= STATUS_VISIBILITY_ENABLED) {
247:                    ensureVisibility();
248:                }
249:
250:                firePropertyChange(PROP_TOOL_TIP, oldToolTip, this .toolTip);
251:            }
252:
253:            /** Create the default tooltip component.
254:             */
255:            protected JComponent createDefaultToolTip() {
256:                return createTextToolTip(false);
257:            }
258:
259:            private JEditorPane createHtmlTextToolTip() {
260:                JEditorPane tt = new JEditorPane() {
261:                    public @Override
262:                    void setSize(int width, int height) {
263:                        Dimension prefSize = getPreferredSize();
264:                        if (width >= prefSize.width) {
265:                            width = prefSize.width;
266:                        } else { // smaller available width
267:                            super .setSize(width, 10000); // the height is unimportant
268:                            prefSize = getPreferredSize(); // re-read new pref width
269:                        }
270:                        if (height >= prefSize.height) { // enough height
271:                            height = prefSize.height;
272:                        }
273:                        super .setSize(width, height);
274:                    }
275:                };
276:
277:                Font font = UIManager.getFont(UI_PREFIX + ".font"); // NOI18N
278:                Color backColor = UIManager.getColor(UI_PREFIX + ".background"); // NOI18N
279:                Color foreColor = UIManager.getColor(UI_PREFIX + ".foreground"); // NOI18N
280:
281:                if (font != null) {
282:                    tt.setFont(font);
283:                }
284:                if (foreColor != null) {
285:                    tt.setForeground(foreColor);
286:                }
287:                if (backColor != null) {
288:                    tt.setBackground(backColor);
289:                }
290:
291:                tt.setOpaque(true);
292:                tt.setBorder(BorderFactory.createCompoundBorder(BorderFactory
293:                        .createLineBorder(tt.getForeground()), BorderFactory
294:                        .createEmptyBorder(0, 3, 0, 3)));
295:                tt.setContentType("text/html"); //NOI18N
296:
297:                return tt;
298:            }
299:
300:            private JTextArea createTextToolTip(final boolean wrapLines) {
301:                JTextArea tt = new JTextArea() {
302:                    public @Override
303:                    void setSize(int width, int height) {
304:                        Dimension prefSize = getPreferredSize();
305:                        if (width >= prefSize.width) {
306:                            width = prefSize.width;
307:                        } else { // smaller available width
308:                            // Set line wrapping and do super.setSize() to determine
309:                            // the real height (it will change due to line wrapping)
310:
311:                            if (wrapLines) {
312:                                setLineWrap(true);
313:                                setWrapStyleWord(true);
314:                            }
315:
316:                            super .setSize(width, 10000); // the height is unimportant
317:                            prefSize = getPreferredSize(); // re-read new pref width
318:                        }
319:                        if (height >= prefSize.height) { // enough height
320:                            height = prefSize.height;
321:                        } else { // smaller available height
322:                            // Check how much can be displayed - cannot rely on line count
323:                            // because line wrapping may display single physical line
324:                            // into several visual lines
325:                            // Before using viewToModel() a setSize() must be called
326:                            // because otherwise the viewToModel() would return -1.
327:                            super .setSize(width, 10000);
328:                            int offset = viewToModel(new Point(0, height));
329:                            Document doc = getDocument();
330:                            Element root = doc.getDefaultRootElement();
331:                            int lineIndex = root.getElementIndex(offset);
332:                            lineIndex--; // go to previous line
333:                            if (lineIndex >= 0) {
334:                                Element lineElem = root.getElement(lineIndex);
335:                                if (lineElem != null) {
336:                                    try {
337:                                        offset = lineElem.getStartOffset();
338:                                        doc.remove(offset, doc.getLength()
339:                                                - offset);
340:                                        doc.insertString(offset, "...", null);
341:                                    } catch (BadLocationException e) {
342:                                        // "..." will likely not be displayed but otherwise should be ok
343:                                    }
344:                                    // Recalculate the prefSize as it may be smaller
345:                                    // than the present preferred height
346:                                    height = Math.min(height,
347:                                            getPreferredSize().height);
348:                                }
349:                            }
350:                        }
351:                        super .setSize(width, height);
352:                    }
353:                };
354:
355:                // bugfix of #43174
356:                tt.setActionMap(new ActionMap());
357:                tt.setInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
358:                        null);
359:
360:                Font font = UIManager.getFont(UI_PREFIX + ".font"); // NOI18N
361:                Color backColor = UIManager.getColor(UI_PREFIX + ".background"); // NOI18N
362:                Color foreColor = UIManager.getColor(UI_PREFIX + ".foreground"); // NOI18N
363:
364:                if (font != null) {
365:                    tt.setFont(font);
366:                }
367:                if (foreColor != null) {
368:                    tt.setForeground(foreColor);
369:                }
370:                if (backColor != null) {
371:                    tt.setBackground(backColor);
372:                }
373:
374:                tt.setOpaque(true);
375:                tt.setBorder(BorderFactory.createCompoundBorder(BorderFactory
376:                        .createLineBorder(tt.getForeground()), BorderFactory
377:                        .createEmptyBorder(0, 3, 0, 3)));
378:
379:                return tt;
380:            }
381:
382:            public void settingsChange(SettingsChangeEvent evt) {
383:            }
384:
385:            public void propertyChange(PropertyChangeEvent evt) {
386:                String propName = evt.getPropertyName();
387:
388:                if (ExtEditorUI.COMPONENT_PROPERTY.equals(propName)) {
389:                    JTextComponent component = (JTextComponent) evt
390:                            .getNewValue();
391:                    if (component != null) { // just installed
392:
393:                        component.addPropertyChangeListener(this );
394:
395:                        disableSwingToolTip(component);
396:
397:                        component.addFocusListener(this );
398:                        if (component.hasFocus()) {
399:                            focusGained(new FocusEvent(component,
400:                                    FocusEvent.FOCUS_GAINED));
401:                        }
402:                        component.addMouseListener(this );
403:                        component.addMouseMotionListener(this );
404:
405:                        GlyphGutter gg = extEditorUI.getGlyphGutter();
406:                        if (gg != null && !glyphListenerAdded) {
407:                            glyphListenerAdded = true;
408:                            gg.addMouseListener(this );
409:                            gg.addMouseMotionListener(this );
410:                        }
411:
412:                    } else { // just deinstalled
413:                        component = (JTextComponent) evt.getOldValue();
414:
415:                        component.removeFocusListener(this );
416:                        component.removePropertyChangeListener(this );
417:
418:                        component.removeMouseListener(this );
419:                        component.removeMouseMotionListener(this );
420:
421:                        GlyphGutter gg = extEditorUI.getGlyphGutter();
422:                        if (gg != null) {
423:                            gg.removeMouseListener(this );
424:                            gg.removeMouseMotionListener(this );
425:                        }
426:                        setToolTipVisible(false);
427:
428:                    }
429:                }
430:
431:                if (JComponent.TOOL_TIP_TEXT_KEY.equals(propName)) {
432:                    JComponent component = (JComponent) evt.getSource();
433:                    disableSwingToolTip(component);
434:
435:                    componentToolTipTextChanged(evt);
436:                }
437:
438:            }
439:
440:            private void disableSwingToolTip(final JComponent component) {
441:                javax.swing.SwingUtilities.invokeLater(new Runnable() {
442:                    public void run() {
443:                        // Prevent default swing tooltip manager
444:                        javax.swing.ToolTipManager.sharedInstance()
445:                                .unregisterComponent(component);
446:
447:                        // Also disable the swing tooltip manager on gutter component
448:                        GlyphGutter gg = extEditorUI.getGlyphGutter();
449:                        if (gg != null) {
450:                            javax.swing.ToolTipManager.sharedInstance()
451:                                    .unregisterComponent(gg);
452:                        }
453:                    }
454:                });
455:            }
456:
457:            /** Update the tooltip by running corresponding action
458:             * {@link ExtKit#buildToolTipAction}. This method gets
459:             * called once the enterTimer fires and it can be overriden
460:             * by children.
461:             */
462:            protected void updateToolTip() {
463:                ExtEditorUI ui = extEditorUI;
464:                if (ui == null)
465:                    return;
466:                JTextComponent comp = ui.getComponent();
467:                if (comp == null)
468:                    return;
469:
470:                if (isGlyphGutterMouseEvent(lastMouseEvent)) {
471:                    setToolTipText(extEditorUI.getGlyphGutter().getToolTipText(
472:                            lastMouseEvent));
473:                } else { // over the text component
474:                    BaseKit kit = Utilities.getKit(comp);
475:                    if (kit != null) {
476:                        Action a = kit
477:                                .getActionByName(ExtKit.buildToolTipAction);
478:                        if (a != null) {
479:                            a.actionPerformed(new ActionEvent(comp, 0, "")); // NOI18N
480:                        }
481:                    }
482:                }
483:            }
484:
485:            /** Set the visibility of the tooltip.
486:             * @param visible whether tooltip should become visible or not.
487:             *  If true the status is changed
488:             * to {@link { #STATUS_VISIBILITY_ENABLED}
489:             * and @link #updateToolTip()}  is called.<BR>
490:             * It is still possible that the tooltip will not be showing
491:             * on the screen in case the tooltip or tooltip text are left
492:             * unchanged.
493:             */
494:            protected void setToolTipVisible(boolean visible) {
495:                if (!visible) { // ensure the timers are stopped
496:                    enterTimer.stop();
497:                    exitTimer.stop();
498:                }
499:
500:                if (visible && status < STATUS_VISIBILITY_ENABLED || !visible
501:                        && status >= STATUS_VISIBILITY_ENABLED) {
502:                    if (visible) { // try to show the tooltip
503:                        if (enabled) {
504:                            setStatus(STATUS_VISIBILITY_ENABLED);
505:                            updateToolTip();
506:                        }
507:
508:                    } else { // hide tip
509:                        if (toolTip != null) {
510:                            if (toolTip.isVisible()) {
511:                                toolTip.setVisible(false);
512:                                PopupManager pm = extEditorUI.getPopupManager();
513:                                if (pm != null) {
514:                                    pm.uninstall(toolTip);
515:                                }
516:                            }
517:                        }
518:
519:                        setStatus(STATUS_HIDDEN);
520:                    }
521:                }
522:            }
523:
524:            /** @return Whether the tooltip is showing on the screen.
525:             * {@link #getStatus() } gives the exact visibility state.
526:             */
527:            public boolean isToolTipVisible() {
528:                return status > STATUS_VISIBILITY_ENABLED;
529:            }
530:
531:            /** @return status of the tooltip visibility. It can
532:             * be {@link #STATUS_HIDDEN}
533:             * or {@link #STATUS_VISIBILITY_ENABLED}
534:             * or {@link #STATUS_TEXT_VISIBLE}
535:             * or {@link #STATUS_COMPONENT_VISIBLE}.
536:             */
537:            public final int getStatus() {
538:                return status;
539:            }
540:
541:            private void setStatus(int status) {
542:                if (this .status != status) {
543:                    int oldStatus = this .status;
544:                    this .status = status;
545:                    firePropertyChange(PROP_STATUS, new Integer(oldStatus),
546:                            new Integer(this .status));
547:                }
548:            }
549:
550:            /** @return the current tooltip text.
551:             */
552:            public String getToolTipText() {
553:                return toolTipText;
554:            }
555:
556:            /**
557:             * Makes the given String displayble. Probably there doesn't exists
558:             * perfect solution for all situation. (someone prefer display those
559:             * squares for undisplayable chars, someone unicode placeholders). So lets
560:             * try do the best compromise.
561:             */
562:            private static String makeDisplayable(String str, Font f) {
563:                if (str == null || f == null) {
564:                    return str;
565:                }
566:                StringBuffer buf = new StringBuffer(str.length());
567:                char[] chars = str.toCharArray();
568:                for (int i = 0; i < chars.length; i++) {
569:                    char c = chars[i];
570:                    switch (c) {
571:                    case '\t':
572:                        buf.append(c);
573:                        break;
574:                    case '\n':
575:                        buf.append(c);
576:                        break;
577:                    case '\r':
578:                        buf.append(c);
579:                        break;
580:                    case '\b':
581:                        buf.append("\\b");
582:                        break; // NOI18N
583:                    case '\f':
584:                        buf.append("\\f");
585:                        break; // NOI18N
586:                    default:
587:                        if (f == null || f.canDisplay(c)) {
588:                            buf.append(c);
589:                        } else {
590:                            buf.append("\\u"); // NOI18N
591:                            String hex = Integer.toHexString(c);
592:                            for (int j = 0; j < 4 - hex.length(); j++) {
593:                                buf.append('0'); //NOI18N
594:                            }
595:                            buf.append(hex);
596:                        }
597:                    }
598:                }
599:                return buf.toString();
600:            }
601:
602:            /** Set the tooltip text to make the tooltip
603:             * to be shown on the screen.
604:             * @param text tooltip text to be displayed.
605:             */
606:            public void setToolTipText(String text) {
607:
608:                final String displayableText = makeDisplayable(text, UIManager
609:                        .getFont(UI_PREFIX + ".font")); //NOI18N
610:
611:                Utilities.runInEventDispatchThread(new Runnable() {
612:                    public void run() {
613:                        String oldText = toolTipText;
614:                        toolTipText = displayableText;
615:
616:                        firePropertyChange(PROP_TOOL_TIP_TEXT, oldText,
617:                                toolTipText);
618:
619:                        if (toolTipText != null) {
620:                            if (toolTipText.startsWith(HTML_PREFIX_LOWERCASE)
621:                                    || toolTipText
622:                                            .startsWith(HTML_PREFIX_UPPERCASE)) {
623:                                JEditorPane jep = createHtmlTextToolTip();
624:                                jep.setText(toolTipText);
625:                                setToolTip(jep);
626:                            } else {
627:                                boolean multiLineText = toolTipText
628:                                        .contains("\n"); //NOI18N
629:                                JTextArea ta = createTextToolTip(!multiLineText);
630:                                ta.setText(toolTipText);
631:                                setToolTip(ta);
632:                            }
633:                        } else { // null text
634:                            if (status == STATUS_TEXT_VISIBLE) {
635:                                setToolTipVisible(false);
636:                            }
637:                        }
638:                    }
639:                });
640:            }
641:
642:            private boolean isGlyphGutterMouseEvent(MouseEvent evt) {
643:                return (evt != null && evt.getSource() == extEditorUI
644:                        .getGlyphGutter());
645:            }
646:
647:            private void ensureVisibility() {
648:                // Find the visual position in the document
649:                JTextComponent component = extEditorUI.getComponent();
650:                if (component != null) {
651:                    // Try to display the tooltip above (or below) the line it corresponds to
652:                    int pos = component.viewToModel(getLastMouseEventPoint());
653:                    Rectangle cursorBounds = null;
654:                    if (pos >= 0) {
655:                        try {
656:                            cursorBounds = component.modelToView(pos);
657:                            if (horizontalBounds == PopupManager.ScrollBarBounds) {
658:
659:                            } else {
660:                                if (placement == PopupManager.AbovePreferred
661:                                        || placement == PopupManager.Above) {
662:                                    // Enlarge the height slightly to not interfere with mouse cursor
663:                                    cursorBounds.y -= MOUSE_EXTRA_HEIGHT;
664:                                    cursorBounds.height += 2 * MOUSE_EXTRA_HEIGHT; // above and below
665:                                } else if (placement == PopupManager.BelowPreferred
666:                                        || placement == PopupManager.Below) {
667:                                    cursorBounds.y = cursorBounds.y
668:                                            + cursorBounds.height
669:                                            + MOUSE_EXTRA_HEIGHT + 1;
670:                                    cursorBounds.height += MOUSE_EXTRA_HEIGHT; // above and below
671:                                }
672:                            }
673:
674:                        } catch (BadLocationException e) {
675:                        }
676:                    }
677:                    if (cursorBounds == null) { // get mose rect
678:                        cursorBounds = new Rectangle(getLastMouseEventPoint(),
679:                                new Dimension(1, 1));
680:                    }
681:
682:                    // updateToolTipBounds();
683:                    PopupManager pm = extEditorUI.getPopupManager();
684:
685:                    if (toolTip != null && toolTip.isVisible()) {
686:                        toolTip.setVisible(false);
687:                    }
688:                    pm.install(toolTip, cursorBounds, placement,
689:                            horizontalBounds, horizontalAdjustment,
690:                            verticalAdjustment);
691:                    if (toolTip != null) {
692:                        toolTip.setVisible(true);
693:                    }
694:                }
695:                exitTimer.restart();
696:            }
697:
698:            /** Helper method to get the identifier
699:             * under the mouse cursor.
700:             * @return string containing identifier under
701:             * mouse cursor.
702:             */
703:            public String getIdentifierUnderCursor() {
704:                String word = null;
705:                if (!isGlyphGutterMouseEvent(lastMouseEvent)) {
706:                    try {
707:                        JTextComponent component = extEditorUI.getComponent();
708:                        BaseTextUI ui = (BaseTextUI) component.getUI();
709:                        Point lmePoint = getLastMouseEventPoint();
710:                        int pos = ui.viewToModel(component, lmePoint);
711:                        if (pos >= 0) {
712:                            BaseDocument doc = (BaseDocument) component
713:                                    .getDocument();
714:                            int eolPos = Utilities.getRowEnd(doc, pos);
715:                            Rectangle eolRect = ui.modelToView(component,
716:                                    eolPos);
717:                            int lineHeight = extEditorUI.getLineHeight();
718:                            if (lmePoint.x <= eolRect.x
719:                                    && lmePoint.y <= eolRect.y + lineHeight) {
720:                                word = Utilities.getIdentifier(doc, pos);
721:                            }
722:                        }
723:                    } catch (BadLocationException e) {
724:                        // word will be null
725:                    }
726:                }
727:
728:                return word;
729:            }
730:
731:            /** @return whether the tooltip support is enabled. If it's
732:             * disabled the tooltip does not become visible.
733:             */
734:            public boolean isEnabled() {
735:                return enabled;
736:            }
737:
738:            /** Set whether the tooltip support is enabled. If it's
739:             * disabled the tooltip does not become visible.
740:             * @param enabled whether the tooltip will be enabled or not.
741:             */
742:            public void setEnabled(boolean enabled) {
743:                if (enabled != this .enabled) {
744:                    this .enabled = enabled;
745:
746:                    firePropertyChange(PROP_ENABLED, enabled ? Boolean.FALSE
747:                            : Boolean.TRUE, enabled ? Boolean.TRUE
748:                            : Boolean.FALSE);
749:
750:                    if (!enabled) {
751:                        setToolTipVisible(false);
752:                    }
753:                }
754:            }
755:
756:            /** @return the delay between stopping
757:             * mouse movement and displaying
758:             * of the tooltip in milliseconds.
759:             */
760:            public int getInitialDelay() {
761:                return enterTimer.getDelay();
762:            }
763:
764:            /** Set the delay between stopping
765:             * mouse movement and displaying
766:             * of the tooltip in milliseconds.
767:             */
768:            public void setInitialDelay(int delay) {
769:                if (enterTimer.getDelay() != delay) {
770:                    int oldDelay = enterTimer.getDelay();
771:                    enterTimer.setDelay(delay);
772:
773:                    firePropertyChange(PROP_INITIAL_DELAY,
774:                            new Integer(oldDelay), new Integer(enterTimer
775:                                    .getDelay()));
776:                }
777:            }
778:
779:            /** @return the delay between displaying
780:             * of the tooltip and its automatic hiding
781:             * in milliseconds.
782:             */
783:            public int getDismissDelay() {
784:                return exitTimer.getDelay();
785:            }
786:
787:            /** Set the delay between displaying
788:             * of the tooltip and its automatic hiding
789:             * in milliseconds.
790:             */
791:            public void setDismissDelay(int delay) {
792:                if (exitTimer.getDelay() != delay) {
793:                    int oldDelay = exitTimer.getDelay();
794:                    exitTimer.setDelay(delay);
795:
796:                    firePropertyChange(PROP_DISMISS_DELAY,
797:                            new Integer(oldDelay), new Integer(exitTimer
798:                                    .getDelay()));
799:                }
800:            }
801:
802:            public void actionPerformed(ActionEvent evt) {
803:                if (evt.getSource() == enterTimer) {
804:                    setToolTipVisible(true);
805:
806:                } else if (evt.getSource() == exitTimer) {
807:                    setToolTipVisible(false);
808:                }
809:            }
810:
811:            public @Override
812:            void mouseClicked(MouseEvent evt) {
813:                lastMouseEvent = evt;
814:                setToolTipVisible(false);
815:            }
816:
817:            public @Override
818:            void mousePressed(MouseEvent evt) {
819:                lastMouseEvent = evt;
820:                setToolTipVisible(false);
821:            }
822:
823:            public @Override
824:            void mouseReleased(MouseEvent evt) {
825:                lastMouseEvent = evt;
826:                setToolTipVisible(false);
827:
828:                // Check that if a selection becomes visible by dragging a mouse
829:                // the tooltip evaluation should be posted.
830:                ExtEditorUI ui = extEditorUI;
831:                if (ui != null) {
832:                    JTextComponent component = ui.getComponent();
833:                    if (enabled && component != null
834:                            && Utilities.isSelectionShowing(component)) {
835:                        enterTimer.restart();
836:                    }
837:                }
838:            }
839:
840:            public @Override
841:            void mouseEntered(MouseEvent evt) {
842:                lastMouseEvent = evt;
843:            }
844:
845:            public @Override
846:            void mouseExited(MouseEvent evt) {
847:                lastMouseEvent = evt;
848:                setToolTipVisible(false);
849:            }
850:
851:            public void mouseDragged(MouseEvent evt) {
852:                lastMouseEvent = evt;
853:                setToolTipVisible(false);
854:            }
855:
856:            public void mouseMoved(MouseEvent evt) {
857:                setToolTipVisible(false);
858:                if (enabled) {
859:                    enterTimer.restart();
860:
861:                }
862:                lastMouseEvent = evt;
863:            }
864:
865:            /** @return last mouse event captured by this support.
866:             * This method can be used by the action that evaluates
867:             * the tooltip.
868:             */
869:            public final MouseEvent getLastMouseEvent() {
870:                return lastMouseEvent;
871:            }
872:
873:            /** Possibly do translation when over the gutter.
874:             */
875:            private Point getLastMouseEventPoint() {
876:                Point p = null;
877:                MouseEvent lme = lastMouseEvent;
878:                if (lme != null) {
879:                    p = lme.getPoint();
880:                    if (lme.getSource() == extEditorUI.getGlyphGutter()) {
881:                        // Over glyph gutter - change coords
882:                        JTextComponent c = extEditorUI.getComponent();
883:                        if (c != null) {
884:                            if (c.getParent() instanceof  JViewport) {
885:                                JViewport vp = (JViewport) c.getParent();
886:                                p = new Point(vp.getViewPosition().x, p.y);
887:                            }
888:                        }
889:                    }
890:                }
891:
892:                return p;
893:            }
894:
895:            /** Called automatically when the
896:             * {@link javax.swing.JComponent#TOOL_TIP_TEXT_KEY}
897:             * property of the corresponding editor component
898:             * gets changed.<BR>
899:             * By default it calls {@link #setToolTipText(java.lang.String)}
900:             * with the new tooltip text of the component.
901:             */
902:            protected void componentToolTipTextChanged(PropertyChangeEvent evt) {
903:                JComponent component = (JComponent) evt.getSource();
904:                setToolTipText(component.getToolTipText());
905:            }
906:
907:            private synchronized PropertyChangeSupport getPCS() {
908:                if (pcs == null) {
909:                    pcs = new PropertyChangeSupport(this );
910:                }
911:                return pcs;
912:            }
913:
914:            /** Add the listener for the property changes. The names
915:             * of the supported properties are defined
916:             * as "PROP_" public static string constants.
917:             * @param listener listener to be added.
918:             */
919:            public void addPropertyChangeListener(
920:                    PropertyChangeListener listener) {
921:                getPCS().addPropertyChangeListener(listener);
922:            }
923:
924:            public void removePropertyChangeListener(
925:                    PropertyChangeListener listener) {
926:                getPCS().removePropertyChangeListener(listener);
927:            }
928:
929:            /** Fire the change of the given property.
930:             * @param propertyName name of the fired property
931:             * @param oldValue old value of the property
932:             * @param newValue new value of the property.
933:             */
934:            protected void firePropertyChange(String propertyName,
935:                    Object oldValue, Object newValue) {
936:                getPCS().firePropertyChange(propertyName, oldValue, newValue);
937:            }
938:
939:            public void focusGained(FocusEvent e) {
940:                //        JComponent component = (JComponent)e.getSource();
941:                //        component.addMouseListener(this);
942:                //        component.addMouseMotionListener(this);
943:                GlyphGutter gg = extEditorUI.getGlyphGutter();
944:                if (gg != null && !glyphListenerAdded) {
945:                    glyphListenerAdded = true;
946:                    gg.addMouseListener(this );
947:                    gg.addMouseMotionListener(this );
948:                }
949:            }
950:
951:            public void focusLost(FocusEvent e) {
952:                /*
953:                JComponent component = (JComponent)e.getSource();
954:                component.removeMouseListener(this);
955:                component.removeMouseMotionListener(this);
956:                GlyphGutter gg = extEditorUI.getGlyphGutter();
957:                if (gg != null) {
958:                    gg.removeMouseListener(this);
959:                    gg.removeMouseMotionListener(this);
960:                }
961:                setToolTipVisible(false);
962:                 */
963:            }
964:
965:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.