KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > editor > ext > CompletionJavaDoc


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20
21 package org.netbeans.editor.ext;
22
23 import java.awt.Color JavaDoc;
24 import java.awt.Rectangle JavaDoc;
25 import java.lang.Comparable JavaDoc;
26 import java.beans.PropertyChangeListener JavaDoc;
27 import java.beans.PropertyChangeEvent JavaDoc;
28 import java.awt.event.ActionEvent JavaDoc;
29 import java.awt.event.ActionListener JavaDoc;
30 import java.lang.StringBuffer JavaDoc;
31
32 import javax.swing.event.ListSelectionListener JavaDoc;
33 import javax.swing.event.ListSelectionEvent JavaDoc;
34 import javax.swing.JList JavaDoc;
35 import javax.swing.SwingUtilities JavaDoc;
36 import javax.swing.event.CaretEvent JavaDoc;
37 import javax.swing.event.CaretListener JavaDoc;
38 import javax.swing.text.JTextComponent JavaDoc;
39 import javax.swing.Timer JavaDoc;
40 import org.netbeans.editor.BaseKit;
41
42 import org.netbeans.editor.WeakTimerListener;
43 import org.netbeans.editor.SettingsChangeListener;
44 import org.netbeans.editor.Settings;
45 import org.netbeans.editor.Utilities;
46 import org.netbeans.editor.ext.ExtSettingsNames;
47 import org.netbeans.editor.ext.ExtSettingsDefaults;
48 import org.netbeans.editor.SettingsChangeEvent;
49 import org.netbeans.editor.SettingsUtil;
50
51 import java.util.*;
52 import org.openide.util.NbBundle;
53
54
55 /**
56  * Support for javadoc in code completion.
57  * Contains also static utilities methods for preparing javadoc HTML content
58  *
59  * @author Martin Roskanin
60  * @since 03/2002
61  */

62 public abstract class CompletionJavaDoc implements ActionListener JavaDoc, SettingsChangeListener, PropertyChangeListener JavaDoc {
63     
64     /** Editor UI supporting this completion */
65     protected ExtEditorUI extEditorUI;
66     
67     // javadoc browser history
68
private List JavaDoc history = new ArrayList(5);
69     
70     private int curHistoryItem = -1;
71     
72     private JavaDocPane pane;
73     private JavaDocView view;
74     private int javaDocDelay;
75     private Timer JavaDoc timer;
76     protected Object JavaDoc currentContent;
77     protected boolean addToHistory;
78     private ListSelectionListener JavaDoc completionListener;
79     private boolean javaDocAutoPopup;
80     private CaretListener JavaDoc caretL;
81
82     public static final String JavaDoc BUNDLE_PREFIX = "javadoc-tag-"; //NOI18N
83
public static final String JavaDoc LOADING = "javadoc-loading"; //NOI18N
84

85     private static final int POPUP_DELAY = 200;
86     
87     
88     /** Creates a new instance of CompletionJavaDoc */
89     public CompletionJavaDoc(ExtEditorUI extEditorUI) {
90         this.extEditorUI = extEditorUI;
91         if (extEditorUI == null)
92             return;
93         
94         // Initialize timer
95
timer = new Timer JavaDoc(0, new WeakTimerListener(this)); // delay will be set later
96
timer.setRepeats(false);
97         Settings.addSettingsChangeListener(this);
98         
99         javaDocDelay = getJavaDocDelay();
100         javaDocAutoPopup = getJavaDocAutoPopup();
101         
102         
103         /**
104          * Hides JavaDoc if completion is hidden.
105          */

106         final ExtEditorUI extUI = extEditorUI;
107         class MyCaretListener implements CaretListener JavaDoc {
108             public void caretUpdate( CaretEvent JavaDoc e ) {
109                 Completion com = extUI.getCompletion();
110                 if (com == null) return;
111                 JDCPopupPanel panel = com.getJDCPopupPanelIfExists();
112                 if (panel == null) return;
113                 if (panel.isVisible() && !com.isPaneVisible()){
114                     setJavaDocVisible(false);
115                 }
116             }
117         }
118         caretL = new MyCaretListener();
119         
120         synchronized (extEditorUI.getComponentLock()) {
121             // if component already installed in ExtEditorUI simulate installation
122
JTextComponent JavaDoc component = extEditorUI.getComponent();
123             if (component != null) {
124                 propertyChange(new PropertyChangeEvent JavaDoc(extEditorUI,
125                                                        ExtEditorUI.COMPONENT_PROPERTY, null, component));
126             }
127
128             extEditorUI.addPropertyChangeListener(this);
129         }
130         
131     }
132
133
134     protected Object JavaDoc convertCompletionObject(Object JavaDoc obj){
135         return obj;
136     }
137     
138     /** If true, the javadoc popup will remain open during completion item change
139      * and "Searching..." dialog will be shown. If the javadoc item will not be found,
140      * the "Javadoc Not Found" message will be also shown
141      * If false, then only valid javadoc content will be shown
142      */

143     protected boolean alwaysDisplayPopup(){
144         return true;
145     }
146
147     protected Comparator getContentComparator() {
148         return null;
149     }
150
151     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
152         String JavaDoc propName = evt.getPropertyName();
153
154         // add completion listener
155
final ExtEditorUI extUI = extEditorUI;
156         class ClearTask implements Runnable JavaDoc {
157             public void run(){
158                 Completion com = extUI.getCompletion();
159                 if (com != null && com.isPaneVisible()){
160                     Object JavaDoc selectedCompletionObject = com.getSelectedValue();
161                     CompletionJavaDoc completionJavaDoc = extUI.getCompletionJavaDoc();
162                     if (selectedCompletionObject == null) {
163                         if ( completionJavaDoc != null && isVisible()){
164                             completionJavaDoc.setContent(null);
165                         }
166                         return;
167                     }
168                     Object JavaDoc selectedValue = convertCompletionObject(selectedCompletionObject);
169
170                     if (alwaysDisplayPopup() == false) setJavaDocVisible(false);
171
172                     if (completionJavaDoc!=null){
173                         if(completionJavaDoc.autoPopup()){
174                             Comparator comparator = getContentComparator();
175                             if (currentContent!=null && !LOADING.equals(currentContent) && (comparator != null ? comparator.compare(currentContent, selectedValue) == 0 : currentContent.equals(selectedValue))){
176                                 if (!isVisible() && alwaysDisplayPopup()) setJavaDocVisible(true);
177                                 return;
178                             }
179                             if (!LOADING.equals(currentContent) && alwaysDisplayPopup())
180                                 completionJavaDoc.setContent(NbBundle.getBundle(BaseKit.class).getString(LOADING));
181                             clearHistory();
182                             completionJavaDoc.setContent(selectedValue);
183                             addToHistory(selectedValue);
184                         }else{
185                             if (isVisible()) completionJavaDoc.setContent(null);
186                         }
187                     }
188                 }
189             }
190         }
191
192         class SelectionObserver implements ListSelectionListener JavaDoc {
193             public void valueChanged(ListSelectionEvent JavaDoc e){
194                 SwingUtilities.invokeLater(new ClearTask());
195             }
196         };
197     
198         if (ExtEditorUI.COMPONENT_PROPERTY.equals(propName)) {
199             JTextComponent JavaDoc component = (JTextComponent JavaDoc)evt.getNewValue();
200             if (component != null) { // just installed
201
component.addCaretListener( caretL );
202
203                 completionListener = new SelectionObserver();
204
205                 Completion completion = extEditorUI.getCompletion();
206                 if (completion != null){
207                     if (completion.getView() instanceof JList JavaDoc){
208                         JList JavaDoc completionList = (JList JavaDoc)completion.getView();
209                         completionList.addListSelectionListener(completionListener);
210                     }
211                 }
212                 
213             } else { // just deinstalled
214

215                 cancelPerformingThread();
216                 component = (JTextComponent JavaDoc)evt.getOldValue();
217
218                 if( component != null ) {
219                     component.removeCaretListener( caretL );
220                 }
221                 
222                 Completion completion = extEditorUI.getCompletion();
223                 if (completion != null){
224                     if (completion.getView() instanceof JList JavaDoc){
225                         JList JavaDoc completionList = (JList JavaDoc)completion.getView();
226                         completionList.removeListSelectionListener(completionListener);
227                     }
228                 }
229                 
230             }
231
232         }
233     }
234     
235     private JDCPopupPanel getJDCPopupPanel(){
236         Completion completion = extEditorUI.getCompletion();
237         if (completion != null){
238             return completion.getJDCPopupPanelIfExists();
239         }
240         return null;
241     }
242
243     /** Returns JavaDoc popup pane */
244     public JavaDocPane getJavaDocPane(){
245         Completion completion = extEditorUI.getCompletion();
246         if (completion != null){
247             return completion.getJDCPopupPanel().getJavaDocPane();
248         }
249         
250         if (pane == null){
251             pane = new ScrollJavaDocPane(extEditorUI);
252         }
253         return pane;
254      }
255     
256     /** Returns JavaDoc View */
257     public JavaDocView getJavaDocView(){
258         if (view == null) {
259             view = new HTMLJavaDocView(getJavaDocBGColor());
260         }
261         return view;
262     }
263     
264     /** Sets javadoc popup window visibility */
265     public void setJavaDocVisible(final boolean visible){
266         final JDCPopupPanel jdc = getJDCPopupPanel();
267         if (jdc!=null){
268             if (visible) getJavaDocPane().setShowWebEnabled(isExternalJavaDocMounted());
269             if (!SwingUtilities.isEventDispatchThread()){
270                 SwingUtilities.invokeLater(
271                 new Runnable JavaDoc() {
272                     public void run() {
273                         jdc.setJavaDocVisible(visible);
274                     }
275                 });
276             }else{
277                 jdc.setJavaDocVisible(visible);
278             }
279         }
280     }
281     
282     public synchronized void addToHistory(Object JavaDoc url){
283         int histSize = history.size();
284         for (int i=curHistoryItem+1; i<histSize; i++){
285             history.remove(history.size()-1);
286         }
287         history.add(url);
288         curHistoryItem = history.size()-1;
289         if (curHistoryItem > 0) getJavaDocPane().setBackEnabled(true);
290         getJavaDocPane().setForwardEnabled(false);
291     }
292     
293     public synchronized void backHistory(){
294         if (curHistoryItem > 0) {
295             curHistoryItem--;
296             setContent(history.get(curHistoryItem), false, false);
297             if (curHistoryItem == 0) getJavaDocPane().setBackEnabled(false);
298             getJavaDocPane().setForwardEnabled(true);
299         }
300     }
301     
302     public synchronized void forwardHistory(){
303         if (curHistoryItem <history.size()-1){
304             curHistoryItem++;
305             setContent(history.get(curHistoryItem), false, false);
306             if (curHistoryItem == history.size()-1) getJavaDocPane().setForwardEnabled(false);
307             getJavaDocPane().setBackEnabled(true);
308         }
309     }
310     
311     public synchronized void clearHistory(){
312         curHistoryItem = -1;
313         history.clear();
314         getJavaDocPane().setBackEnabled(false);
315         getJavaDocPane().setForwardEnabled(false);
316     }
317     
318     public boolean isVisible(){
319         return getJavaDocPane().getComponent().isVisible();
320     }
321     
322     /** Interrupts timer that is responsible for delayed popup of javadoc window */
323     public void cancelPerformingThread(){
324         timer.stop();
325     }
326     
327     protected Object JavaDoc getCurrentContent(){
328         if (currentContent instanceof CompletionQuery.ResultItemAssociatedObject){
329             return ((CompletionQuery.ResultItemAssociatedObject)currentContent).getAssociatedObject();
330         }
331         return currentContent;
332     }
333
334     synchronized void clearContent() {
335         cancelPerformingThread();
336         currentContent = null;
337     }
338
339     /** Sets content of javadoc
340      * @param content it is Object of the java member such as JCClass, JCMethod, JCField or JCConstructor
341      * @param postRequest if false, javadoc window is popuped without delay
342      * @param addToHistory if true, the content item will be added to history queue
343      */

344     public synchronized void setContent(Object JavaDoc content, boolean postRequest, boolean addToHistory){
345         timer.stop();
346         if (content == null) {
347             currentContent = null;
348             setJavaDocVisible(false);
349             return;
350         }
351         currentContent = content;
352         this.addToHistory = addToHistory;
353         
354         if (postRequest){
355             //timer.setInitialDelay(javaDocDelay);
356
timer.setInitialDelay(POPUP_DELAY);
357             //timer.setDelay(javaDocDelay);
358
timer.setDelay(POPUP_DELAY);
359             timer.start();
360         }else{
361             actionPerformed(null);
362         }
363         
364         
365     }
366     
367     /** Sets content of javadoc
368      * @param content it is Object of the java member such as JCClass, JCMethod, JCField or JCConstructor
369      * @param postRequest if false, javadoc window is popuped without delay
370      */

371     public synchronized void setContent(Object JavaDoc content, boolean postRequest){
372         setContent(content, postRequest, true);
373     }
374     
375     /** Sets content of javadoc with postRequest setted to true
376      * @see #setContent(java.lang.Object, boolean)
377      */

378     public void setContent(Object JavaDoc content){
379         setContent(content, true);
380     }
381     
382     /** Immediately sets Content of javadoc withou popup delay
383      * @param content String representation of the displayed text.
384      * In the case of current implementation it is an HTML document
385      * Can be <code>null</code> in this case javaDoc popup will be hidden
386      */

387     public void setContent(String JavaDoc content){
388         if (content == null){
389             setJavaDocVisible(false);
390             return;
391         }
392         getJavaDocView().setContent(content);
393     }
394     
395     /**
396      * Invoked when an action occurs.
397      */

398     public synchronized void actionPerformed(ActionEvent JavaDoc e) {
399         //[PENDING] - javaDoc for standalone editor
400
}
401
402     /** Retrieve a background color of javadoc from options */
403     private Color JavaDoc getJavaDocBGColor(){
404         Class JavaDoc kitClass = Utilities.getKitClass(extEditorUI.getComponent());
405         if (kitClass != null) {
406             return (Color JavaDoc)SettingsUtil.getValue(kitClass,
407                       ExtSettingsNames.JAVADOC_BG_COLOR,
408                       ExtSettingsDefaults.defaultJavaDocBGColor);
409         }
410         return ExtSettingsDefaults.defaultJavaDocBGColor;
411     }
412
413     /** Retrieve a javadoc popup delay from options */
414     private int getJavaDocDelay(){
415         Class JavaDoc kitClass = Utilities.getKitClass(extEditorUI.getComponent());
416         if (kitClass != null) {
417             return ((Integer JavaDoc)SettingsUtil.getValue(kitClass,
418                       ExtSettingsNames.JAVADOC_AUTO_POPUP_DELAY,
419                       ExtSettingsDefaults.defaultJavaDocAutoPopupDelay)).intValue();
420         }
421         return ExtSettingsDefaults.defaultJavaDocAutoPopupDelay.intValue();
422     }
423
424     /** Retrieve a auto popup of javadoc property from options */
425     private boolean getJavaDocAutoPopup(){
426         Class JavaDoc kitClass = Utilities.getKitClass(extEditorUI.getComponent());
427         if (kitClass != null) {
428             return ((Boolean JavaDoc)SettingsUtil.getValue(kitClass,
429                       ExtSettingsNames.JAVADOC_AUTO_POPUP,
430                       ExtSettingsDefaults.defaultJavaDocAutoPopup)).booleanValue();
431         }
432         return ExtSettingsDefaults.defaultJavaDocAutoPopup.booleanValue();
433     }
434     
435     /** Returns whether javadoc window should be invoked automatically */
436     public boolean autoPopup(){
437         return javaDocAutoPopup;
438     }
439     
440     public void settingsChange(SettingsChangeEvent evt) {
441         if (ExtSettingsNames.JAVADOC_BG_COLOR.equals(evt.getSettingName())){
442             getJavaDocView().setBGColor(getJavaDocBGColor());
443         }
444         
445         if (ExtSettingsNames.JAVADOC_AUTO_POPUP_DELAY.equals(evt.getSettingName())){
446             javaDocDelay = getJavaDocDelay();
447         }
448
449         if (ExtSettingsNames.JAVADOC_AUTO_POPUP.equals(evt.getSettingName())){
450             javaDocAutoPopup = getJavaDocAutoPopup();
451         }
452         
453     }
454     
455
456     
457     /** Parses given link such as <code>java.awt.Component#addHierarchyListener</code>
458      * and returns parsed Object
459      * @return Object of JCClass, JCMethod, JCConstructor or JCField
460      */

461     public Object JavaDoc parseLink(String JavaDoc link, Object JavaDoc baseObj){
462         return null;
463     }
464
465     
466     protected String JavaDoc getTagName(CompletionJavaDoc.JavaDocTagItem tag){
467         try {
468             return NbBundle.getBundle(BaseKit.class).getString(BUNDLE_PREFIX+tag.getName());
469         } catch (MissingResourceException e) {
470             return tag.getName();
471         }
472     }
473     
474     
475     public void goToSource(){
476     }
477     
478     public void openInExternalBrowser(){
479     }
480     
481     public boolean isExternalJavaDocMounted(){
482         return false;
483     }
484     
485     public interface JavaDocTagItem extends Comparable JavaDoc{
486         public String JavaDoc getName();
487         public String JavaDoc getText();
488     }
489
490 }
491
Popular Tags