Source Code Cross Referenced for Completion.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.EventQueue;
045:        import java.awt.event.ActionListener;
046:        import java.awt.event.ActionEvent;
047:        import java.beans.PropertyChangeListener;
048:        import java.beans.PropertyChangeEvent;
049:        import javax.swing.Timer;
050:        import javax.swing.SwingUtilities;
051:        import javax.swing.text.JTextComponent;
052:        import javax.swing.event.CaretListener;
053:        import javax.swing.event.CaretEvent;
054:        import javax.swing.event.DocumentListener;
055:        import javax.swing.event.DocumentEvent;
056:        import org.netbeans.editor.BaseDocument;
057:        import org.netbeans.editor.Settings;
058:        import org.netbeans.editor.SettingsChangeListener;
059:        import org.netbeans.editor.SettingsChangeEvent;
060:        import org.netbeans.editor.SettingsUtil;
061:        import org.netbeans.editor.Utilities;
062:        import org.netbeans.editor.WeakTimerListener;
063:        import javax.swing.text.BadLocationException;
064:        import javax.swing.event.ListSelectionListener;
065:        import org.openide.util.NbBundle;
066:        import org.openide.util.RequestProcessor;
067:
068:        /**
069:         * General Completion display formatting and services
070:         *
071:         * @author Miloslav Metelka
072:         * @version 1.00
073:         */
074:
075:        public class Completion implements  PropertyChangeListener,
076:                SettingsChangeListener, ActionListener {
077:
078:            /** Editor UI supporting this completion */
079:            protected ExtEditorUI extEditorUI;
080:
081:            /** Completion query providing query support for this completion */
082:            private CompletionQuery query;
083:
084:            /** Last result retrieved for completion. It can become null
085:             * if the document was modified so the replacement position
086:             * would be invalid.
087:             */
088:            private CompletionQuery.Result lastResult;
089:
090:            private boolean keyPressed = false;
091:
092:            /** Completion view component displaying the completion help */
093:            private CompletionView view;
094:
095:            /** Component (usually scroll-pane) holding the view and the title
096:             * and possibly other necessary components.
097:             */
098:            private ExtCompletionPane pane;
099:
100:            private JavaDocPane javaDocPane;
101:
102:            private JDCPopupPanel jdcPopupPanel;
103:
104:            private boolean autoPopup;
105:
106:            private int autoPopupDelay;
107:
108:            private int refreshDelay;
109:
110:            private boolean instantSubstitution;
111:
112:            Timer timer;
113:            Timer docChangeTimer;
114:
115:            private DocumentListener docL;
116:            private CaretListener caretL;
117:
118:            private PropertyChangeListener docChangeL;
119:
120:            private int caretPos = -1;
121:
122:            // old providers was called serialy from AWT, emulate it by RP queue
123:            private static RequestProcessor serializingRequestProcessor;
124:
125:            // sample property at static initialized, but allow dynamic disabling later
126:            private static final String PROP_DEBUG_COMPLETION = "editor.debug.completion"; // NOI18N
127:            private static final boolean DEBUG_COMPLETION = Boolean
128:                    .getBoolean(PROP_DEBUG_COMPLETION);
129:
130:            // Every asynchronous task can be splitted into several subtasks.
131:            // The task can between subtasks using simple test determine whether
132:            // it was not cancelled.
133:            // It emulates #28475 RequestProcessor enhancement request.
134:            private CancelableRunnable cancellable = new CancelableRunnable() {
135:                public void run() {
136:                }
137:            };
138:            public boolean provokedByAutoPopup;
139:
140:            public Completion(ExtEditorUI extEditorUI) {
141:                this .extEditorUI = extEditorUI;
142:
143:                // Initialize timer
144:                timer = new Timer(0, new WeakTimerListener(this )); // delay will be set later
145:                timer.setRepeats(false);
146:
147:                docChangeTimer = new Timer(0, new WeakTimerListener(
148:                        new ActionListener() {
149:                            public void actionPerformed(ActionEvent e) {
150:                                refreshImpl(false); //??? why do not we batch them by posting it?
151:                            }
152:                        }));
153:                docChangeTimer.setRepeats(false);
154:
155:                // Create document listener
156:                class CompletionDocumentListener implements  DocumentListener {
157:
158:                    private void processTimer() {
159:                        docChangeTimer.stop();
160:                        setKeyPressed(true);
161:                        invalidateLastResult();
162:                        docChangeTimer.setInitialDelay(refreshDelay);
163:                        docChangeTimer.setDelay(refreshDelay);
164:                        docChangeTimer.start();
165:                    }
166:
167:                    public void insertUpdate(DocumentEvent evt) {
168:                        trace("ENTRY insertUpdate"); // NOI18N
169:                        processTimer();
170:                    }
171:
172:                    public void removeUpdate(DocumentEvent evt) {
173:                        trace("ENTRY removeUpdate"); // NOI18N
174:                        processTimer();
175:                    }
176:
177:                    public void changedUpdate(DocumentEvent evt) {
178:                    }
179:                }
180:                ;
181:                docL = new CompletionDocumentListener();
182:
183:                class CompletionCaretListener implements  CaretListener {
184:                    public void caretUpdate(CaretEvent e) {
185:                        trace("ENTRY caretUpdate"); // NOI18N
186:                        if (!isPaneVisible()) {
187:                            // cancel timer if caret moved
188:                            cancelRequestImpl();
189:                        } else {
190:                            //refresh completion only if a pane is already visible
191:                            refreshImpl(true);
192:                        }
193:                    }
194:                }
195:                ;
196:                caretL = new CompletionCaretListener();
197:
198:                Settings.addSettingsChangeListener(this );
199:
200:                synchronized (extEditorUI.getComponentLock()) {
201:                    // if component already installed in ExtEditorUI simulate installation
202:                    JTextComponent component = extEditorUI.getComponent();
203:                    if (component != null) {
204:                        propertyChange(new PropertyChangeEvent(extEditorUI,
205:                                ExtEditorUI.COMPONENT_PROPERTY, null, component));
206:                    }
207:
208:                    extEditorUI.addPropertyChangeListener(this );
209:                }
210:            }
211:
212:            public void settingsChange(SettingsChangeEvent evt) {
213:                Class kitClass = Utilities.getKitClass(extEditorUI
214:                        .getComponent());
215:
216:                if (kitClass != null) {
217:                    autoPopup = SettingsUtil.getBoolean(kitClass,
218:                            ExtSettingsNames.COMPLETION_AUTO_POPUP,
219:                            ExtSettingsDefaults.defaultCompletionAutoPopup);
220:
221:                    autoPopupDelay = SettingsUtil
222:                            .getInteger(
223:                                    kitClass,
224:                                    ExtSettingsNames.COMPLETION_AUTO_POPUP_DELAY,
225:                                    ExtSettingsDefaults.defaultCompletionAutoPopupDelay);
226:
227:                    refreshDelay = SettingsUtil.getInteger(kitClass,
228:                            ExtSettingsNames.COMPLETION_REFRESH_DELAY,
229:                            ExtSettingsDefaults.defaultCompletionRefreshDelay);
230:
231:                    instantSubstitution = SettingsUtil
232:                            .getBoolean(
233:                                    kitClass,
234:                                    ExtSettingsNames.COMPLETION_INSTANT_SUBSTITUTION,
235:                                    ExtSettingsDefaults.defaultCompletionInstantSubstitution);
236:
237:                }
238:            }
239:
240:            public void propertyChange(PropertyChangeEvent evt) {
241:                String propName = evt.getPropertyName();
242:
243:                if (ExtEditorUI.COMPONENT_PROPERTY.equals(propName)) {
244:                    JTextComponent component = (JTextComponent) evt
245:                            .getNewValue();
246:                    if (component != null) { // just installed
247:
248:                        settingsChange(null);
249:
250:                        BaseDocument doc = Utilities.getDocument(component);
251:                        if (doc != null) {
252:                            doc.addDocumentListener(docL);
253:                        }
254:
255:                        component.addCaretListener(caretL);
256:                    } else { // just deinstalled
257:
258:                        setPaneVisible(false);
259:
260:                        component = (JTextComponent) evt.getOldValue();
261:
262:                        BaseDocument doc = Utilities.getDocument(component);
263:                        if (doc != null) {
264:                            doc.removeDocumentListener(docL);
265:                        }
266:
267:                        if (component != null) {
268:                            component.removeCaretListener(caretL);
269:                        }
270:                    }
271:
272:                } else if ("document".equals(propName)) { // NOI18N
273:                    if (evt.getOldValue() instanceof  BaseDocument) {
274:                        ((BaseDocument) evt.getOldValue())
275:                                .removeDocumentListener(docL);
276:                    }
277:                    if (evt.getNewValue() instanceof  BaseDocument) {
278:                        ((BaseDocument) evt.getNewValue())
279:                                .addDocumentListener(docL);
280:                    }
281:
282:                }
283:
284:            }
285:
286:            public CompletionPane getPane() {
287:                return (CompletionPane) getExtPane();
288:            }
289:
290:            public ExtCompletionPane getExtPane() {
291:                if (pane == null) {
292:                    pane = new ScrollCompletionPane(extEditorUI);
293:                }
294:                return pane;
295:            }
296:
297:            protected CompletionView createView() {
298:                return new ListCompletionView();
299:            }
300:
301:            public final CompletionView getView() {
302:                if (view == null) {
303:                    view = createView();
304:                }
305:                return view;
306:            }
307:
308:            protected CompletionQuery createQuery() {
309:                return null;
310:            }
311:
312:            public final CompletionQuery getQuery() {
313:                if (query == null) {
314:                    query = createQuery();
315:                }
316:                return query;
317:            }
318:
319:            public JavaDocPane getJavaDocPane() {
320:                if (javaDocPane == null) {
321:                    javaDocPane = new ScrollJavaDocPane(extEditorUI);
322:                }
323:                return javaDocPane;
324:            }
325:
326:            /**
327:             * Get panel holding all aids (completion and documentation panes).
328:             * @return JDCPopupPanel or <code>null</code>
329:             */
330:            public final JDCPopupPanel getJDCPopupPanelIfExists() {
331:                return jdcPopupPanel;
332:            }
333:
334:            /**
335:             * Get panel holding all aids (completion and documentation panes).
336:             * @return JDCPopupPanel never <code>null</code>
337:             */
338:            public JDCPopupPanel getJDCPopupPanel() {
339:                if (jdcPopupPanel == null) {
340:                    jdcPopupPanel = new JDCPopupPanel(extEditorUI,
341:                            getExtPane(), this );
342:                }
343:                return jdcPopupPanel;
344:            }
345:
346:            /** Get the result of the last valid completion query or null
347:             * if there's no valid result available.
348:             */
349:            public synchronized final CompletionQuery.Result getLastResult() {
350:                return lastResult;
351:            }
352:
353:            /** Reset the result of the last valid completion query. This
354:             * is done for example after the document was modified.
355:             */
356:            public synchronized final void invalidateLastResult() {
357:                currentTask().cancel();
358:                lastResult = null;
359:                caretPos = -1;
360:            }
361:
362:            private synchronized void setKeyPressed(boolean value) {
363:                keyPressed = value;
364:            }
365:
366:            private synchronized boolean isKeyPressed() {
367:                return keyPressed;
368:            }
369:
370:            public synchronized Object getSelectedValue() {
371:                if (lastResult != null) {
372:                    int index = getView().getSelectedIndex();
373:                    if (index >= 0 && index < lastResult.getData().size()) {
374:                        return lastResult.getData().get(index);
375:                    }
376:                }
377:                return null;
378:            }
379:
380:            /** Return true if the completion should popup automatically */
381:            public boolean isAutoPopupEnabled() {
382:                return autoPopup;
383:            }
384:
385:            /** Return true when the pane exists and is visible.
386:             * This is the preferred method of testing the visibility of the pane
387:             * instead of <tt>getPane().isVisible()</tt> that forces
388:             * the creation of the pane.
389:             */
390:            public boolean isPaneVisible() {
391:                return (pane != null && pane.isVisible());
392:            }
393:
394:            /** Set the visibility of the view. This method should
395:             * be used mainly for hiding the completion pane. If used
396:             * with visible set to true it calls the <tt>popup(false)</tt>.
397:             */
398:            public void setPaneVisible(boolean visible) {
399:                trace("ENTRY setPaneVisible " + visible); // NOI18N
400:                if (visible) {
401:                    if (extEditorUI.getComponent() != null) {
402:                        popupImpl(false);
403:                    }
404:                } else {
405:                    if (pane != null) {
406:                        cancelRequestImpl();
407:                        invalidateLastResult();
408:                        getJDCPopupPanel().setCompletionVisible(false);
409:                        caretPos = -1;
410:                    }
411:                }
412:            }
413:
414:            public void completionCancel() {
415:                trace("ENTRY completionCancel"); // NOI18N
416:                if (pane != null) {
417:                    cancelRequestImpl();
418:                    invalidateLastResult();
419:                    caretPos = -1;
420:                }
421:            }
422:
423:            /** Refresh the contents of the view if it's currently visible.
424:             * @param postRequest post the request instead of refreshing the view
425:             *   immediately. The <tt>ExtSettingsNames.COMPLETION_REFRESH_DELAY</tt>
426:             *   setting stores the number of milliseconds before the view is refreshed.
427:             */
428:            public void refresh(boolean postRequest) {
429:                trace("ENTRY refresh " + postRequest); // NOI18N
430:                refreshImpl(postRequest);
431:            }
432:
433:            private synchronized void refreshImpl(final boolean postRequest) {
434:
435:                // exit immediatelly
436:                if (isPaneVisible() == false)
437:                    return;
438:
439:                class RefreshTask implements  Runnable {
440:                    private final boolean batch;
441:
442:                    RefreshTask(boolean batch) {
443:                        this .batch = batch;
444:                    }
445:
446:                    public void run() {
447:                        if (isPaneVisible()) {
448:                            timer.stop();
449:                            if (batch) {
450:                                timer.setInitialDelay(refreshDelay);
451:                                timer.setDelay(refreshDelay);
452:                                timer.start();
453:                            } else {
454:                                actionPerformed(null);
455:                            }
456:                        }
457:                    }
458:                }
459:                ;
460:
461:                SwingUtilities.invokeLater(new RefreshTask(postRequest));
462:            }
463:
464:            /** Get the help and show it in the view. If the view is already visible
465:             * perform the refresh of the view.
466:             * @param postRequest post the request instead of displaying the view
467:             *   immediately. The <tt>ExtSettingsNames.COMPLETION_AUTO_POPUP_DELAY</tt>
468:             *   setting stores the number of milliseconds before the view is displayed.
469:             *   If the user presses a key until the delay expires nothing is shown.
470:             *   This guarantees that the user which knows what to write will not be
471:             *   annoyed with the unnecessary help.
472:             */
473:            public void popup(boolean postRequest) {
474:                trace("ENTRY popup " + postRequest); // NOI18N
475:                popupImpl(postRequest);
476:            }
477:
478:            private synchronized void popupImpl(boolean postRequest) {
479:                if (isPaneVisible()) {
480:                    refreshImpl(postRequest);
481:                } else {
482:                    timer.stop();
483:                    if (postRequest) {
484:                        timer.setInitialDelay(autoPopupDelay);
485:                        timer.setDelay(autoPopupDelay);
486:                        timer.start();
487:                    } else {
488:                        actionPerformed(null);
489:                    }
490:                }
491:            }
492:
493:            /** Cancel last request for either displaying or refreshing
494:             * the pane. It resets the internal timer.
495:             */
496:            public void cancelRequest() {
497:                trace("ENTRY cancelRequest"); // NOI18N
498:                cancelRequestImpl();
499:            }
500:
501:            private synchronized void cancelRequestImpl() {
502:                timer.stop();
503:            }
504:
505:            /** Called to do either displaying or refreshing of the view.
506:             * This method can be called either directly or because of the timer has fired.
507:             * @param evt event describing the timer firing or null
508:             *   if the method was called directly because of the synchronous
509:             *   showing/refreshing the view.
510:             */
511:            public synchronized void actionPerformed(ActionEvent evt) {
512:
513:                if (jdcPopupPanel == null)
514:                    extEditorUI.getCompletionJavaDoc(); //init javaDoc
515:
516:                final JTextComponent component = extEditorUI.getComponent();
517:                BaseDocument doc = Utilities.getDocument(component);
518:
519:                if (component != null && doc != null) {
520:
521:                    provokedByAutoPopup = evt != null;
522:
523:                    try {
524:                        if ((caretPos != -1)
525:                                && (Utilities.getRowStart(component, component
526:                                        .getCaret().getDot()) != Utilities
527:                                        .getRowStart(component, caretPos))
528:                                && ((component.getCaret().getDot() - caretPos) > 0)) {
529:                            getJDCPopupPanel().setCompletionVisible(false);
530:                            caretPos = -1;
531:                            return;
532:                        }
533:                    } catch (BadLocationException ble) {
534:                    }
535:
536:                    caretPos = component.getCaret().getDot();
537:
538:                    // show progress view
539:                    class PendingTask extends CancelableRunnable {
540:                        public void run() {
541:                            if (cancelled())
542:                                return;
543:                            SwingUtilities.invokeLater(new Runnable() {
544:                                public void run() {
545:                                    if (cancelled())
546:                                        return;
547:                                    performWait();
548:                                }
549:                            });
550:                        }
551:                    }
552:                    ;
553:
554:                    // perform query and show results
555:                    class QueryTask extends CancelableRunnable {
556:                        private final CancelableRunnable wait;
557:                        private final boolean isPaneVisible;
558:
559:                        public QueryTask(CancelableRunnable wait,
560:                                boolean isPaneVisible) {
561:                            this .wait = wait;
562:                            this .isPaneVisible = isPaneVisible;
563:                        }
564:
565:                        public void run() {
566:                            if (cancelled())
567:                                return;
568:                            try {
569:                                performQuery(component);
570:                            } catch (ThreadDeath td) {
571:                                throw td;
572:                            } catch (Throwable exc) {
573:                                exc.printStackTrace();
574:                            } finally {
575:                                wait.cancel();
576:                                if (cancelled())
577:                                    return;
578:                                SwingUtilities.invokeLater(new Runnable() {
579:                                    public void run() {
580:                                        if (cancelled())
581:                                            return;
582:                                        CompletionQuery.Result res = lastResult;
583:                                        if (res != null) {
584:                                            if (instantSubstitution
585:                                                    && res.getData().size() == 1
586:                                                    && !isPaneVisible
587:                                                    && instantSubstitution(caretPos)) {
588:                                                setPaneVisible(false);
589:                                                return;
590:                                            }
591:                                        }
592:
593:                                        performResults();
594:                                    }
595:                                });
596:                            }
597:                        }
598:
599:                        void cancel() {
600:                            super .cancel();
601:                            wait.cancel();
602:                        }
603:                    }
604:                    ;
605:
606:                    // update current task: cancel pending task and fire new one
607:
608:                    currentTask().cancel();
609:
610:                    RequestProcessor rp;
611:                    boolean reentrantProvider = getQuery() instanceof  CompletionQuery.SupportsSpeculativeInvocation;
612:                    if (reentrantProvider) {
613:                        rp = RequestProcessor.getDefault();
614:                    } else {
615:                        rp = getSerialiazingRequestProcessor();
616:                    }
617:
618:                    CancelableRunnable wait = new PendingTask();
619:                    CancelableRunnable task = new QueryTask(wait, getPane()
620:                            .isVisible());
621:                    currentTask(task);
622:                    if (provokedByAutoPopup == false) {
623:                        RequestProcessor.getDefault().post(wait, 100);
624:                    }
625:                    rp.post(task);
626:                }
627:            }
628:
629:            /**
630:             * Show wait completion result. Always called from AWT.
631:             */
632:            private void performWait() {
633:                getPane().setTitle(
634:                        NbBundle.getBundle(org.netbeans.editor.BaseKit.class)
635:                                .getString("ext.Completion.wait"));
636:                getView().setResult((CompletionQuery.Result) null);
637:                if (isPaneVisible()) {
638:                    getJDCPopupPanel().refresh();
639:                } else {
640:                    getJDCPopupPanel().setCompletionVisible(true);
641:                }
642:            }
643:
644:            /**
645:             * Execute complegtion query subtask
646:             */
647:            private void performQuery(final JTextComponent target) {
648:
649:                BaseDocument doc = Utilities.getDocument(target);
650:                long start = System.currentTimeMillis();
651:                try {
652:                    lastResult = getQuery().query(target, caretPos,
653:                            doc.getSyntaxSupport());
654:                } finally {
655:                    trace("performQuery took "
656:                            + (System.currentTimeMillis() - start) + "ms"); // NOI18N
657:                    setKeyPressed(false);
658:                }
659:            }
660:
661:            /**
662:             * Show result popup. Always called from AWT.
663:             */
664:            protected void performResults() {
665:                // sample
666:                CompletionQuery.Result res = lastResult;
667:                if (res != null) {
668:
669:                    if (instantSubstitution && res.getData().size() == 1
670:                            && !isPaneVisible()
671:                            && instantSubstitution(caretPos))
672:                        return;
673:
674:                    getPane().setTitle(res.getTitle());
675:                    getView().setResult(res);
676:                    if (isPaneVisible()) {
677:                        getJDCPopupPanel().refresh();
678:                    } else {
679:                        getJDCPopupPanel().setCompletionVisible(true);
680:                    }
681:                } else {
682:                    getJDCPopupPanel().setCompletionVisible(false);
683:
684:                    if (!isKeyPressed()) {
685:                        caretPos = -1;
686:                    } else {
687:                        setKeyPressed(false);
688:                    }
689:                }
690:            }
691:
692:            /** Performs instant text substitution, provided that result contains only one 
693:             *  item and completion has been invoked at the end of the word.
694:             *  @param caretPos offset position of the caret
695:             */
696:            public boolean instantSubstitution(int caretPos) {
697:                trace("ENTRY instantSubstitution " + caretPos); // NOI18N
698:                return instantSubstitutionImpl(caretPos);
699:            }
700:
701:            private synchronized boolean instantSubstitutionImpl(int caretPos) {
702:                if (getLastResult() == null)
703:                    return false;
704:                JTextComponent comp = extEditorUI.getComponent();
705:                try {
706:                    if (comp != null) {
707:                        int[] block = Utilities.getIdentifierBlock(comp,
708:                                caretPos);
709:                        if (block == null || block[1] == caretPos)
710:                            return getLastResult().substituteText(0, false);
711:                    }
712:                } catch (BadLocationException ble) {
713:                }
714:                return false;
715:            }
716:
717:            /** Substitute the document's text with the text
718:             * that is appopriate for the selection
719:             * in the view. This function is usually triggered
720:             * upon pressing the Enter key.
721:             * @return true if the substitution was performed
722:             *  false if not.
723:             */
724:            public synchronized boolean substituteText(boolean shift) {
725:                trace("ENTRY substituteText " + shift); // NOI18N
726:                if (lastResult != null) {
727:                    int index = getView().getSelectedIndex();
728:                    if (index >= 0) {
729:                        lastResult.substituteText(index, shift);
730:                    }
731:                    return true;
732:                } else {
733:                    return false;
734:                }
735:            }
736:
737:            public synchronized boolean substituteSimpleText() {
738:                return false;
739:            }
740:
741:            /** Substitute the text with the longest common
742:             * part of all the entries appearing in the view.
743:             * This function is usually triggered
744:             * upon pressing the Tab key.
745:             * @return true if the substitution was performed
746:             *  false if not.
747:             */
748:            public synchronized boolean substituteCommonText() {
749:                trace("ENTRY substituteCommonText"); // NOI18N
750:                if (lastResult != null) {
751:                    int index = getView().getSelectedIndex();
752:                    if (index >= 0) {
753:                        lastResult.substituteCommonText(index);
754:                    }
755:                    return true;
756:                } else {
757:                    return false;
758:                }
759:            }
760:
761:            // Task management ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
762:
763:            /**
764:             * Make given task current.
765:             */
766:            private void currentTask(CancelableRunnable task) {
767:                cancellable = task;
768:            }
769:
770:            /**
771:             * Get current task
772:             */
773:            private CancelableRunnable currentTask() {
774:                return cancellable;
775:            }
776:
777:            /**
778:             * Multistage task can test its cancel status after every atomic
779:             * (non-cancellable) stage.
780:             */
781:            abstract class CancelableRunnable implements  Runnable {
782:                private boolean cancelled = false;
783:
784:                boolean cancelled() {
785:                    return cancelled;
786:                }
787:
788:                void cancel() {
789:                    cancelled = true;
790:                }
791:            }
792:
793:            /**
794:             * Get serializing request processor.
795:             */
796:            private synchronized RequestProcessor getSerialiazingRequestProcessor() {
797:                if (serializingRequestProcessor == null) {
798:                    serializingRequestProcessor = new RequestProcessor(
799:                            "editor.completion", 1);// NOI18N
800:                }
801:                return serializingRequestProcessor;
802:            }
803:
804:            // Debug support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
805:
806:            private static void trace(String msg) {
807:                if (DEBUG_COMPLETION
808:                        && Boolean.getBoolean(PROP_DEBUG_COMPLETION)) {
809:                    synchronized (System.err) {
810:                        System.err.println(msg);
811:                    }
812:                }
813:            }
814:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.