1 19 20 package org.openide.text; 21 22 23 import java.awt.*; 24 import java.io.*; 25 import java.util.logging.Level ; 26 import java.util.logging.Logger ; 27 import javax.swing.*; 28 import javax.swing.border.Border ; 29 import javax.swing.text.*; 30 import org.openide.awt.UndoRedo; 31 import org.openide.cookies.EditorCookie; 32 import org.openide.util.*; 33 import org.openide.util.actions.SystemAction; 34 import org.openide.windows.*; 35 36 38 public class CloneableEditor extends CloneableTopComponent implements CloneableEditorSupport.Pane { 39 private static final String HELP_ID = "editing.editorwindow"; static final long serialVersionUID = -185739563792410059L; 41 42 43 protected JEditorPane pane; 44 45 46 private CloneableEditorSupport support; 47 48 49 private boolean initialized; 50 51 53 private int cursorPosition = -1; 54 55 57 60 private Component customComponent; 61 private JToolBar customToolbar; 62 63 64 public CloneableEditor() { 65 this(null); 66 } 67 68 72 public CloneableEditor(CloneableEditorSupport support) { 73 super(); 74 this.support = support; 75 76 updateName(); 77 _setCloseOperation(); 78 } 79 @SuppressWarnings ("deprecation") 80 private void _setCloseOperation() { 81 setCloseOperation(CLOSE_EACH); 82 } 83 84 89 protected CloneableEditorSupport cloneableEditorSupport() { 90 return support; 91 } 92 93 95 public int getPersistenceType() { 96 return TopComponent.PERSISTENCE_ONLY_OPENED; 97 } 98 99 105 public HelpCtx getHelpCtx() { 106 Object kit = support.cesKit(); 107 HelpCtx fromKit = kit == null ? null : HelpCtx.findHelp(kit); 108 109 if (fromKit != null) { 110 return fromKit; 111 } else { 112 return new HelpCtx(HELP_ID); 113 } 114 } 115 116 121 public boolean canClose() { 122 boolean result = super.canClose(); 123 124 if (result) { 125 SwingUtilities.invokeLater( 126 new Runnable () { 127 public void run() { 128 if (pane != null) { 130 Document doc = support.createStyledDocument(pane.getEditorKit()); 131 pane.setDocument(doc); 132 pane.setEditorKit(null); 133 } 134 135 removeAll(); 136 initialized = false; 137 } 138 } 139 ); 140 } 141 142 return result; 143 } 144 145 147 protected void componentShowing() { 148 super.componentShowing(); 149 initialize(); 150 } 151 152 153 private void initialize() { 154 if (initialized || discard()) { 155 return; 156 } 157 158 initialized = true; 159 160 Task prepareTask = support.prepareDocument(); 161 162 prepareTask.waitFinished(); 164 165 Document doc = support.getDocument(); 166 167 setLayout(new BorderLayout()); 168 169 final QuietEditorPane pane = new QuietEditorPane(); 170 171 pane.getAccessibleContext().setAccessibleName( 172 NbBundle.getMessage(CloneableEditor.class, "ACS_CloneableEditor_QuietEditorPane", this.getName()) 173 ); 174 pane.getAccessibleContext().setAccessibleDescription( 175 NbBundle.getMessage( 176 CloneableEditor.class, "ACSD_CloneableEditor_QuietEditorPane", 177 this.getAccessibleContext().getAccessibleDescription() 178 ) 179 ); 180 181 this.pane = pane; 182 183 javax.swing.ActionMap am = getActionMap(); 185 186 javax.swing.ActionMap paneMap = pane.getActionMap(); 189 am.setParent(paneMap); 190 191 paneMap.put(DefaultEditorKit.cutAction, getAction(DefaultEditorKit.cutAction)); 194 paneMap.put(DefaultEditorKit.copyAction, getAction(DefaultEditorKit.copyAction)); 195 paneMap.put("delete", getAction(DefaultEditorKit.deleteNextCharAction)); paneMap.put(DefaultEditorKit.pasteAction, getAction(DefaultEditorKit.pasteAction)); 197 198 pane.setEditorKit(support.cesKit()); 199 200 pane.setDocument(doc); 201 202 if (doc instanceof NbDocument.CustomEditor) { 203 NbDocument.CustomEditor ce = (NbDocument.CustomEditor) doc; 204 customComponent = ce.createEditor(pane); 205 206 if (customComponent == null) { 207 throw new IllegalStateException ( 208 "Document:" + doc +" implementing NbDocument.CustomEditor may not" +" return null component" 211 ); } 213 214 add(support.wrapEditorComponent(customComponent), BorderLayout.CENTER); 215 } else { 217 JScrollPane noBorderPane = new JScrollPane(pane); 219 pane.setBorder(null); 220 add(support.wrapEditorComponent(noBorderPane), BorderLayout.CENTER); 221 } 222 223 if (doc instanceof NbDocument.CustomToolbar) { 224 NbDocument.CustomToolbar ce = (NbDocument.CustomToolbar) doc; 225 customToolbar = ce.createToolbar(pane); 226 227 if (customToolbar == null) { 228 throw new IllegalStateException ( 229 "Document:" + doc +" implementing NbDocument.CustomToolbar may not" +" return null toolbar" 232 ); } 234 235 Border b = (Border ) UIManager.get("Nb.Editor.Toolbar.border"); customToolbar.setBorder(b); 237 add(customToolbar, BorderLayout.NORTH); 238 } 239 240 pane.setWorking(QuietEditorPane.ALL); 241 242 if (cursorPosition != -1) { 244 Caret caret = pane.getCaret(); 245 246 if (caret != null) { 247 caret.setDot(cursorPosition); 248 } 249 } 250 251 support.ensureAnnotationsLoaded(); 252 } 253 254 protected CloneableTopComponent createClonedObject() { 255 return support.createCloneableTopComponent(); 256 } 257 258 263 protected void componentOpened() { 264 super.componentOpened(); 265 266 CloneableEditorSupport ces = cloneableEditorSupport(); 267 268 if (ces != null) { 269 ces.firePropertyChange(EditorCookie.Observable.PROP_OPENED_PANES, null, null); 270 } 271 } 272 273 278 protected void componentClosed() { 279 super.componentClosed(); 280 281 CloneableEditorSupport ces = cloneableEditorSupport(); 282 283 if (ces != null) { 284 ces.firePropertyChange(EditorCookie.Observable.PROP_OPENED_PANES, null, null); 285 } 286 } 287 288 294 @SuppressWarnings ("deprecation") 295 public void open(Workspace workspace) { 296 if (discard()) { 297 Logger.getAnonymousLogger().warning( 298 "Can not open " + this + " component," +" its support environment is not valid" +" [support=" + support + ", env=" +((support == null) ? null : support.cesEnv()) + "]" 302 ); } else { 304 dockIfNeeded(); 305 super.open(workspace); 306 } 307 } 308 309 312 protected boolean closeLast() { 313 if (!support.canClose()) { 314 return false; 316 } 317 318 support.notifyClosed(); 320 321 if (support.getLastSelected() == this) { 322 support.setLastSelected(null); 323 } 324 325 return true; 326 } 327 328 331 public UndoRedo getUndoRedo() { 332 return support.getUndoRedo(); 333 } 334 335 @Override 336 public Action[] getActions() { 337 Action[] a = super.getActions(); 338 339 try { 340 ClassLoader l = Lookup.getDefault().lookup(ClassLoader .class); 341 342 if (l == null) { 343 l = getClass().getClassLoader(); 344 } 345 346 Class <? extends SystemAction> c = Class.forName("org.openide.actions.FileSystemAction", true, l).asSubclass(SystemAction.class); SystemAction ra = SystemAction.findObject(c, true); 348 349 Action[] a2 = new Action[a.length + 1]; 350 System.arraycopy(a, 0, a2, 0, a.length); 351 a2[a.length] = ra; 352 return a2; 353 } catch (Exception ex) { 354 } 356 357 return a; 358 } 359 360 362 @SuppressWarnings ("deprecation") 363 public void requestFocus() { 364 super.requestFocus(); 365 366 if ((customComponent != null) && !SwingUtilities.isDescendingFrom(pane, customComponent)) { 367 customComponent.requestFocus(); 368 } else if (pane != null) { 369 pane.requestFocus(); 370 } 371 } 372 373 375 @SuppressWarnings ("deprecation") 376 public boolean requestFocusInWindow() { 377 super.requestFocusInWindow(); 378 379 if ((customComponent != null) && !SwingUtilities.isDescendingFrom(pane, customComponent)) { 380 return customComponent.requestFocusInWindow(); 381 } else if (pane != null) { 382 return pane.requestFocusInWindow(); 383 } 384 385 return false; 386 } 387 388 @SuppressWarnings ("deprecation") 389 public boolean requestDefaultFocus() { 390 if ((customComponent != null) && !SwingUtilities.isDescendingFrom(pane, customComponent)) { 391 return customComponent.requestFocusInWindow(); 392 } else if (pane != null) { 393 return pane.requestFocusInWindow(); 394 } 395 396 return false; 397 } 398 399 401 public Dimension getPreferredSize() { 402 @SuppressWarnings ("deprecation") 403 Rectangle bounds = WindowManager.getDefault().getCurrentWorkspace().getBounds(); 404 405 return new Dimension(bounds.width / 2, bounds.height / 2); 406 } 407 408 private Action getAction(String key) { 409 if (key == null) { 410 return null; 411 } 412 413 EditorKit kit = support.cesKit(); 415 416 if (kit == null) { 418 return null; 419 } 420 421 Action[] actions = kit.getActions(); 422 423 for (int i = 0; i < actions.length; i++) { 424 if (key.equals(actions[i].getValue(Action.NAME))) { 425 return actions[i]; 426 } 427 } 428 429 return null; 430 } 431 432 435 protected void componentActivated() { 436 support.setLastSelected(this); 437 } 438 439 446 public void updateName() { 447 final CloneableEditorSupport ces = cloneableEditorSupport(); 448 449 if (ces != null) { 450 Mutex.EVENT.writeAccess( 451 new Runnable () { 452 public void run() { 453 String name = ces.messageHtmlName(); 454 setHtmlDisplayName(name); 455 name = ces.messageName(); 456 setDisplayName(name); 457 setName(name); 459 setToolTipText(ces.messageToolTip()); 460 } 461 } 462 ); 463 } 464 } 465 466 protected String preferredID() { 468 final CloneableEditorSupport ces = cloneableEditorSupport(); 469 470 if (ces != null) { 471 return ces.documentID(); 472 } 473 474 return ""; 475 } 476 477 public void writeExternal(ObjectOutput out) throws IOException { 478 super.writeExternal(out); 479 480 out.writeObject((support != null) ? support.cesEnv() : null); 484 485 int pos = 0; 488 489 JEditorPane p = pane; 493 494 if (p != null) { 495 Caret caret = p.getCaret(); 496 497 if (caret != null) { 498 pos = caret.getDot(); 499 } else { 500 if (p instanceof QuietEditorPane) { 501 int lastPos = ((QuietEditorPane) p).getLastPosition(); 502 503 if (lastPos == -1) { 504 Logger.getLogger(CloneableEditor.class.getName()).log(Level.WARNING, null, 505 new java.lang.IllegalStateException ("Pane=" + 506 p + 507 "was not initialized yet!")); 508 } else { 509 pos = lastPos; 510 } 511 } else { 512 Document doc = ((support != null) ? support.getDocument() : null); 513 514 if (doc != null) { 516 Logger.getLogger(CloneableEditor.class.getName()).log(Level.WARNING, null, 517 new java.lang.IllegalStateException ("Caret is null in editor pane=" + 518 p + 519 "\nsupport=" + 520 support + 521 "\ndoc=" + 522 doc)); 523 } 524 } 525 } 526 } 527 528 out.writeObject(new Integer (pos)); 529 } 530 531 public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { 532 super.readExternal(in); 533 534 int offset; 535 536 Object firstObject = in.readObject(); 537 538 if (firstObject instanceof CloneableOpenSupport.Env) { 541 CloneableOpenSupport.Env env = (CloneableOpenSupport.Env) firstObject; 542 CloneableOpenSupport os = env.findCloneableOpenSupport(); 543 support = (CloneableEditorSupport) os; 544 } 545 546 offset = ((Integer ) in.readObject()).intValue(); 548 549 if (!discard()) { 550 cursorPosition = offset; 551 } 552 553 updateName(); 554 } 555 556 563 protected Object writeReplace() throws ObjectStreamException { 564 if (discard()) { 565 throw new NotSerializableException("Serializing component is invalid: " + this); } 567 568 return super.writeReplace(); 569 } 570 571 578 protected Object readResolve() throws ObjectStreamException { 579 if (discard()) { 580 throw new java.io.InvalidObjectException ("Deserialized component is invalid: " + this); } else { 582 support.initializeCloneableEditor(this); 583 584 return this; 585 } 586 } 587 588 591 private boolean discard() { 592 return (support == null) || !support.cesEnv().isValid(); 593 } 594 595 597 private void dockIfNeeded() { 598 Mode ourMode = WindowManager.getDefault().findMode(this); 600 if( null == ourMode ) { 601 604 TopComponent activeTc = TopComponent.getRegistry().getActivated(); 606 if( null != activeTc ) { 607 ourMode = WindowManager.getDefault().findMode( activeTc ); 608 if( !WindowManager.getDefault().isEditorMode( ourMode ) ) 609 ourMode = null; 610 } 611 if( null == ourMode ) 612 ourMode = WindowManager.getDefault().findMode( "editor" ); 613 if( null != ourMode ) { 614 ourMode.dockInto( this ); 615 } else { 616 Logger.getAnonymousLogger().warning("The window system cannot find the default editor mode." ); 618 } 619 } 620 } 621 622 public CloneableTopComponent getComponent() { 626 return this; 627 } 628 629 public JEditorPane getEditorPane() { 630 initialize(); 631 632 return pane; 633 } 634 635 638 public void ensureVisible() { 639 open(); 640 requestVisible(); 641 } 642 } 643 | Popular Tags |