1 19 20 21 package org.netbeans.editor.ext; 22 23 import java.awt.Color ; 24 import java.awt.Rectangle ; 25 import java.lang.Comparable ; 26 import java.beans.PropertyChangeListener ; 27 import java.beans.PropertyChangeEvent ; 28 import java.awt.event.ActionEvent ; 29 import java.awt.event.ActionListener ; 30 import java.lang.StringBuffer ; 31 32 import javax.swing.event.ListSelectionListener ; 33 import javax.swing.event.ListSelectionEvent ; 34 import javax.swing.JList ; 35 import javax.swing.SwingUtilities ; 36 import javax.swing.event.CaretEvent ; 37 import javax.swing.event.CaretListener ; 38 import javax.swing.text.JTextComponent ; 39 import javax.swing.Timer ; 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 62 public abstract class CompletionJavaDoc implements ActionListener , SettingsChangeListener, PropertyChangeListener { 63 64 65 protected ExtEditorUI extEditorUI; 66 67 private List 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 timer; 76 protected Object currentContent; 77 protected boolean addToHistory; 78 private ListSelectionListener completionListener; 79 private boolean javaDocAutoPopup; 80 private CaretListener caretL; 81 82 public static final String BUNDLE_PREFIX = "javadoc-tag-"; public static final String LOADING = "javadoc-loading"; 85 private static final int POPUP_DELAY = 200; 86 87 88 89 public CompletionJavaDoc(ExtEditorUI extEditorUI) { 90 this.extEditorUI = extEditorUI; 91 if (extEditorUI == null) 92 return; 93 94 timer = new Timer (0, new WeakTimerListener(this)); timer.setRepeats(false); 97 Settings.addSettingsChangeListener(this); 98 99 javaDocDelay = getJavaDocDelay(); 100 javaDocAutoPopup = getJavaDocAutoPopup(); 101 102 103 106 final ExtEditorUI extUI = extEditorUI; 107 class MyCaretListener implements CaretListener { 108 public void caretUpdate( CaretEvent 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 JTextComponent component = extEditorUI.getComponent(); 123 if (component != null) { 124 propertyChange(new PropertyChangeEvent (extEditorUI, 125 ExtEditorUI.COMPONENT_PROPERTY, null, component)); 126 } 127 128 extEditorUI.addPropertyChangeListener(this); 129 } 130 131 } 132 133 134 protected Object convertCompletionObject(Object obj){ 135 return obj; 136 } 137 138 143 protected boolean alwaysDisplayPopup(){ 144 return true; 145 } 146 147 protected Comparator getContentComparator() { 148 return null; 149 } 150 151 public void propertyChange(PropertyChangeEvent evt) { 152 String propName = evt.getPropertyName(); 153 154 final ExtEditorUI extUI = extEditorUI; 156 class ClearTask implements Runnable { 157 public void run(){ 158 Completion com = extUI.getCompletion(); 159 if (com != null && com.isPaneVisible()){ 160 Object 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 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 { 193 public void valueChanged(ListSelectionEvent e){ 194 SwingUtilities.invokeLater(new ClearTask()); 195 } 196 }; 197 198 if (ExtEditorUI.COMPONENT_PROPERTY.equals(propName)) { 199 JTextComponent component = (JTextComponent )evt.getNewValue(); 200 if (component != null) { component.addCaretListener( caretL ); 202 203 completionListener = new SelectionObserver(); 204 205 Completion completion = extEditorUI.getCompletion(); 206 if (completion != null){ 207 if (completion.getView() instanceof JList ){ 208 JList completionList = (JList )completion.getView(); 209 completionList.addListSelectionListener(completionListener); 210 } 211 } 212 213 } else { 215 cancelPerformingThread(); 216 component = (JTextComponent )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 ){ 225 JList completionList = (JList )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 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 257 public JavaDocView getJavaDocView(){ 258 if (view == null) { 259 view = new HTMLJavaDocView(getJavaDocBGColor()); 260 } 261 return view; 262 } 263 264 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 () { 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 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 323 public void cancelPerformingThread(){ 324 timer.stop(); 325 } 326 327 protected Object 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 344 public synchronized void setContent(Object 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(POPUP_DELAY); 357 timer.setDelay(POPUP_DELAY); 359 timer.start(); 360 }else{ 361 actionPerformed(null); 362 } 363 364 365 } 366 367 371 public synchronized void setContent(Object content, boolean postRequest){ 372 setContent(content, postRequest, true); 373 } 374 375 378 public void setContent(Object content){ 379 setContent(content, true); 380 } 381 382 387 public void setContent(String content){ 388 if (content == null){ 389 setJavaDocVisible(false); 390 return; 391 } 392 getJavaDocView().setContent(content); 393 } 394 395 398 public synchronized void actionPerformed(ActionEvent e) { 399 } 401 402 403 private Color getJavaDocBGColor(){ 404 Class kitClass = Utilities.getKitClass(extEditorUI.getComponent()); 405 if (kitClass != null) { 406 return (Color )SettingsUtil.getValue(kitClass, 407 ExtSettingsNames.JAVADOC_BG_COLOR, 408 ExtSettingsDefaults.defaultJavaDocBGColor); 409 } 410 return ExtSettingsDefaults.defaultJavaDocBGColor; 411 } 412 413 414 private int getJavaDocDelay(){ 415 Class kitClass = Utilities.getKitClass(extEditorUI.getComponent()); 416 if (kitClass != null) { 417 return ((Integer )SettingsUtil.getValue(kitClass, 418 ExtSettingsNames.JAVADOC_AUTO_POPUP_DELAY, 419 ExtSettingsDefaults.defaultJavaDocAutoPopupDelay)).intValue(); 420 } 421 return ExtSettingsDefaults.defaultJavaDocAutoPopupDelay.intValue(); 422 } 423 424 425 private boolean getJavaDocAutoPopup(){ 426 Class kitClass = Utilities.getKitClass(extEditorUI.getComponent()); 427 if (kitClass != null) { 428 return ((Boolean )SettingsUtil.getValue(kitClass, 429 ExtSettingsNames.JAVADOC_AUTO_POPUP, 430 ExtSettingsDefaults.defaultJavaDocAutoPopup)).booleanValue(); 431 } 432 return ExtSettingsDefaults.defaultJavaDocAutoPopup.booleanValue(); 433 } 434 435 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 461 public Object parseLink(String link, Object baseObj){ 462 return null; 463 } 464 465 466 protected String 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 { 486 public String getName(); 487 public String getText(); 488 } 489 490 } 491 | Popular Tags |