1 19 20 package org.netbeans.core.output; 21 22 import java.util.HashMap ; 23 import java.util.HashSet ; 24 import java.util.Iterator ; 25 import java.io.PipedReader ; 26 import java.io.PipedWriter ; 27 import java.io.Reader ; 28 import java.io.OutputStreamWriter ; 29 import java.io.IOException ; 30 import java.io.FileWriter ; 31 import java.io.File ; 32 33 import java.awt.*; 34 import java.awt.event.*; 35 import java.awt.datatransfer.*; 36 import java.beans.PropertyChangeListener ; 37 import java.beans.PropertyChangeEvent ; 38 import java.util.ArrayList ; 39 import java.util.Observable ; 40 import java.util.Observer ; 41 import java.util.Set ; 42 import javax.swing.AbstractAction ; 43 44 import javax.swing.JComponent ; 45 import javax.swing.JPanel ; 46 import javax.swing.KeyStroke ; 47 import javax.swing.JPopupMenu ; 48 import javax.swing.JMenuItem ; 49 import javax.swing.JSplitPane ; 50 import javax.swing.SwingUtilities ; 51 import javax.swing.text.Keymap ; 52 53 import org.openide.ErrorManager; 54 import org.openide.windows.*; 55 import org.openide.awt.MouseUtils; 56 import org.openide.actions.CutAction; 57 import org.openide.actions.DeleteAction; 58 import org.openide.actions.PasteAction; 59 import org.openide.actions.CopyAction; 60 import org.openide.actions.FindAction; 61 import org.openide.util.io.NullOutputStream; 62 import org.openide.util.NbBundle; 63 import org.openide.util.Mutex; 64 import org.openide.util.datatransfer.*; 65 import org.openide.util.actions.ActionPerformer; 66 import org.openide.util.actions.SystemAction; 67 import org.openide.util.actions.CallbackSystemAction; 68 69 import org.netbeans.lib.terminalemulator.*; 70 import org.openide.util.Lookup; 71 72 81 82 public class OutputTabInner extends TopComponent 83 implements InputOutput, PropertyChangeListener { 84 85 86 public static final String ICON_RESOURCE = 87 "/org/netbeans/core/resources/frames/output.gif"; 89 91 private boolean focusTaken = false; 92 93 94 private Reader inReader; 95 96 PipedWriter inWriter = new PipedWriter (); 97 98 99 private boolean errSeparated = false; 100 private Boolean inputVisible = null; 101 private boolean errVisible = false; 102 103 104 private JSplitPane splitpane = null; 105 106 107 109 private static final long serialVersionUID =3276412782250080205L; 110 111 private OutTermPane output; 112 113 private OutTermPane error = null; 114 115 117 private boolean hideOnly = false; 118 119 122 private boolean openedInWinSys; 123 private final Object LOCK_OPENED_IN_WINSYS = new Object (); 124 125 OutputTabInner(final String name) { 126 synchronized (OutputTabInner.class) { 127 128 output = new OutTermPane(this); 129 130 synchronized(OutputView.ioCache) { 131 OutputView.ioCache.put(name, this); 132 } 133 134 Mutex.EVENT.readAccess(new Runnable () { 135 public void run() { 136 output.setName("StdOut"); getAccessibleContext ().setAccessibleName ( 139 NbBundle.getBundle (OutputTabInner.class).getString ("ACSN_OutputWindow")); 140 getAccessibleContext ().setAccessibleDescription ( 141 NbBundle.getBundle (OutputTabInner.class).getString ("ACSD_OutputWindow")); 142 setBorder (null); 143 add (output); 144 setName (name); 145 } 146 }); 147 148 TopComponent.getRegistry().addPropertyChangeListener( 149 org.openide.util.WeakListener.propertyChange(this, TopComponent.getRegistry())); 150 151 getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( 152 KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.CTRL_DOWN_MASK), 153 "discard"); 155 getActionMap().put("discard", new DiscardAction()); 156 } 157 } 158 159 private class DiscardAction extends AbstractAction { 160 public void actionPerformed (ActionEvent ae) { 161 OutputView view = (OutputView) SwingUtilities.getAncestorOfClass( 162 OutputView.class, OutputTabInner.this); 163 if (view != null) { 164 view.discardTab(OutputTabInner.this); 165 } 166 } 167 } 168 169 public int getPersistenceType() { 170 return TopComponent.PERSISTENCE_ONLY_OPENED; 171 } 172 173 public void layout() { 174 if (splitpane != null) { 175 splitpane.setBounds (0, 0, getWidth(), getHeight()); 176 } else { 177 output.setBounds (0, 0, getWidth(), getHeight()); 178 } 179 } 180 181 private synchronized OutTermPane getErrorTerm (boolean create) { 182 if (error == null && create) { 183 error = new OutTermPane (this); 184 error.setName("StdErr"); Mutex.EVENT.readAccess(new SplitPaneInstaller()); 186 } 187 return error; 188 } 189 190 private class SplitPaneInstaller implements Runnable { 191 public void run() { 192 splitpane = new JSplitPane (); 193 if (splitpane.getComponentOrientation() == ComponentOrientation.RIGHT_TO_LEFT) { 194 splitpane.setLeftComponent(error); 195 splitpane.setRightComponent(output); 196 } else { 197 splitpane.setLeftComponent(output); 198 splitpane.setRightComponent(error); 199 } 200 splitpane.setDividerLocation(getWidth() / 2); 201 add (splitpane); 202 } 203 } 204 205 207 private class SplitPaneRemover implements Runnable { 208 public void run() { 209 if (splitpane != null) { 212 remove (splitpane); 213 } 214 error = null; 215 add (output); 216 Container parent = getParent (); 217 if (parent != null) parent.validate (); 218 } 219 } 220 221 public synchronized Object writeReplace() throws java.io.ObjectStreamException { 222 if (!this.equals(OutputView.getFactory().getStdOutputTab())) { 226 return null; 227 } 228 229 if (replace == null) { 230 replace = new Replace(this.equals(OutputView.getFactory().getStdOutputTab())); 231 } 232 return replace; 233 } 234 235 public Term getTerm() { 238 return getTerm( true ); 239 } 240 241 public Term getTerm(boolean fromOutputPane) { 244 if ( fromOutputPane ) { 245 return output.getTerm(); 246 } else { 247 return getErrorTerm(true).getTerm(); 248 } 249 } 250 251 259 public String toString () { 260 Term term = getTerm( true ); 261 if ( term == null ) 262 return ""; 264 StringBuffer buf = new StringBuffer (); 265 for (int i=0; i<=term.getCursorCoord().row; i++) { 266 if ( i > 0 ) 267 buf.append('\n'); 268 buf.append( term.getRowText( i ) ); 269 } 270 return buf.toString(); 271 } 272 273 private Replace replace; 274 275 276 static class Replace implements java.io.Serializable { 277 278 boolean defaultInstance; 279 280 private static final long serialVersionUID =-3126744916624172415L; 281 282 public Replace (boolean defaultInstance) { 283 this.defaultInstance = defaultInstance; 284 } 285 286 287 public Object readResolve() throws java.io.ObjectStreamException { 288 if ( defaultInstance ) 289 return OutputView.getFactory().getStdOutputTab(); 290 else 291 return null; 292 } 293 } 294 295 void ensureOpen() { 296 Mutex.EVENT.readAccess(new Runnable () { 300 public void run() { 301 if (isClosed()) { 302 OutputView.findDefault().openInOV(OutputTabInner.this); 304 } 305 } 306 }); 307 } 308 309 static String getOutDisplayName() { 310 return NbBundle.getBundle(OutputTabInner.class).getString("CTL_OutputWindow"); 311 } 312 313 317 318 protected void componentActivated () { 319 output.activated(); 320 } 321 322 323 protected void componentDeactivated () { 324 output.deactivated(); 325 } 326 327 public void requestFocus () { 328 super.requestFocus(); 329 output.requestFocus(); 330 } 331 332 public boolean requestFocusInWindow () { 333 super.requestFocusInWindow(); 334 boolean result = output.requestFocusInWindow(); 335 return result; 336 } 337 338 342 public boolean isFocusTaken() { 343 return focusTaken; 344 } 345 346 348 public void setFocusTaken(boolean value) { 349 focusTaken = value; 350 } 351 352 private boolean firstOut=true; 353 public org.openide.windows.OutputWriter getOut() { 354 if (firstOut) { 355 select(); 356 firstOut = false; 357 } 358 return output.writer; 359 } 360 361 public void select() { 362 364 365 Mutex.EVENT.readAccess(new Runnable () { 366 public void run() { 367 ensureOpen(); 368 OutputView.findDefault().requestVisible(OutputTabInner.this); 369 } 370 }); 371 373 } 374 375 public org.openide.windows.OutputWriter getErr() { 376 if (errSeparated) { 378 return getErrorTerm(true).writer; 379 } 380 else return output.writer; 381 } 382 383 386 public java.io.Reader getIn() { 387 flushReader(); 390 if ( inputVisible == null || inputVisible.booleanValue() ) 392 setInputVisible(true); 393 return inReader; 394 } 395 396 public void setErrSeparated(boolean value) { 397 if (errSeparated != value) { 398 errSeparated = value; 399 if (errVisible != errSeparated) { 400 setErrVisible(errSeparated); 401 } 402 } 403 } 404 405 public java.io.Reader flushReader() { 406 inWriter = new PipedWriter (); 408 try { 409 inReader = new PipedReader (inWriter); 410 } catch (java.io.IOException ex) { 411 ErrorManager.getDefault().notify(ex); 412 return null; 413 } 414 return inReader; 415 } 416 417 public void setOutputVisible(boolean param) { 418 if (param) { 420 Mutex.EVENT.readAccess(new Runnable () { 421 public void run() { 422 ensureOpen(); 423 } 424 }); 425 } 426 else { 427 hideOnly = true; 428 doClose(); 429 } 430 } 431 432 public void setErrVisible(boolean value) { 433 if (errSeparated || errVisible != value ) { 434 errVisible = value; 435 if (errVisible) { 436 getErrorTerm(true); 439 } else { 440 if (error != null) { 441 Mutex.EVENT.readAccess(new SplitPaneRemover()); 442 } 443 } 444 } 445 } 446 447 public boolean isClosed() { 448 boolean isInContainerTopComponent = false; 451 Component p = getParent(); 452 if(p instanceof javax.swing.JComponent ) { 453 javax.swing.JComponent parent = (javax.swing.JComponent )p; 454 Object value = parent.getClientProperty("ContainerTopComponent"); if(value instanceof Boolean ) { 456 isInContainerTopComponent = ((Boolean )value).booleanValue(); 457 } 458 } 459 460 return !isOpenedInWinSys() && !isInContainerTopComponent; 461 } 462 463 protected void componentOpened() { 464 super.componentOpened(); 465 setOpenedInWinSys(true); 466 } 467 468 protected void componentClosed() { 469 super.componentClosed(); 470 setOpenedInWinSys(false); 471 } 472 473 private void setOpenedInWinSys(boolean o) { 474 synchronized(LOCK_OPENED_IN_WINSYS) { 475 openedInWinSys = o; 476 } 477 } 478 479 private boolean isOpenedInWinSys() { 480 synchronized(LOCK_OPENED_IN_WINSYS) { 481 return openedInWinSys; 482 } 483 } 484 485 public void setInputVisible(boolean param) { 486 if (param) { 488 Mutex.EVENT.readAccess(new Runnable () { 489 public void run() { 490 ensureOpen(); 491 } 492 }); 493 } 494 inputVisible = param ? Boolean.TRUE : Boolean.FALSE; 495 output.setReadWrite( param ); 496 } 497 498 public boolean isErrSeparated() { 499 return errSeparated; 501 } 502 503 public void closeInputOutput() { 504 doClose(); 506 try { 507 inWriter.flush(); 508 inWriter.close(); 509 } catch (IOException ioe) { 510 } catch (NullPointerException npe) { 512 } 514 output.writer.close(); 515 if (error != null) { 516 error.writer.close(); 517 } 518 } 519 520 private void doClose() { 521 Mutex.EVENT.readAccess(new Runnable () { 522 public void run() { 523 if(isDisplayable()) { 524 OutputView.findDefault().discardTab(OutputTabInner.this); 525 } 526 } 527 }); 528 } 529 530 public void open () { 531 OutputView.findDefault().openInOV(this); 532 } 533 534 public void propertyChange(PropertyChangeEvent evt) { 536 if(TopComponent.Registry.PROP_OPENED.equals(evt.getPropertyName())) { 537 Object oldValue = evt.getOldValue(); 538 Object newValue = evt.getNewValue(); 539 540 if(!hideOnly 541 && oldValue instanceof Set && ((Set )oldValue).contains(this) && newValue instanceof Set && !((Set )newValue).contains(this)) { output.doClear(); 544 if (error != null) { 545 error.doClear(); 546 } 547 } 548 hideOnly = false; 549 } 550 } 551 552 private static OutputSettings outputSettings () { 553 return (OutputSettings)OutputSettings.findObject (OutputSettings.class, true); 554 } 555 556 557 558 private static HashSet keyStrokeSet = null; 561 562 private static HashSet keyStrokeSet2 = null; 564 565 private static void updateKeyStrokeSet() { 566 keyStrokeSet.clear(); 567 keyStrokeSet.addAll( java.util.Arrays.asList( ((Keymap )Lookup.getDefault ().lookup ( Keymap .class ) ).getBoundKeyStrokes()) ); 568 for (int ks = KeyEvent.VK_A; ks <= KeyEvent.VK_Z; ks++) 569 keyStrokeSet.add( KeyStroke.getKeyStroke( ks, Event.ALT_MASK ) ); 570 571 KeyStroke ks1 = KeyStroke.getKeyStroke(new Character ((char)('T'-64)), 574 Event.CTRL_MASK|Event.SHIFT_MASK); 575 KeyStroke ks2 = KeyStroke.getKeyStroke(new Character ((char)('T'-64)), 576 Event.CTRL_MASK); 577 keyStrokeSet2 = (HashSet ) keyStrokeSet.clone(); 578 keyStrokeSet2.add(ks1); 579 keyStrokeSet2.add(ks2); 580 } 581 582 583 private static HashSet getCommonKeyStrokeSet() { 584 585 if (keyStrokeSet != null) 586 return keyStrokeSet; 587 588 590 keyStrokeSet = new HashSet (); 591 592 Keymap map = (Keymap )org.openide.util.Lookup.getDefault().lookup(Keymap .class); 594 if (map instanceof Observable ) { 597 Observable o = (Observable )map; 598 o.addObserver(new Observer () { 599 public void update(Observable o, Object arg) { 600 updateKeyStrokeSet(); 601 } 602 }); 603 } 604 605 updateKeyStrokeSet(); 606 607 return keyStrokeSet; 608 } 609 610 private static HashSet getCommonKeyStrokeSet2() { 611 getCommonKeyStrokeSet(); 612 return keyStrokeSet2; 613 } 614 615 616 617 public static final class OutTermPane extends JPanel implements ActionPerformer, 618 ActionListener, PropertyChangeListener , Runnable { 619 620 static final long serialVersionUID = -633812012958420549L; 621 622 private static final String REDIR_EXT = ".out"; 624 625 TermOutputWriter writer; 626 627 628 OutputTabInner tab; 629 private boolean findNextEnabled = false; 630 631 632 633 private static CopyAction copy = (CopyAction)CopyAction.get (CopyAction.class); 634 private static FindAction find = (FindAction)FindAction.get (FindAction.class); 635 private static CutAction cut = (CutAction) CutAction.findObject(CutAction.class, true); 636 private static DeleteAction delete = (DeleteAction) DeleteAction.findObject(DeleteAction.class, true); 637 private static PasteAction paste = (PasteAction) PasteAction.findObject(PasteAction.class, true); 638 639 640 private static NextOutJumpAction nextAction = (NextOutJumpAction)NextOutJumpAction.get (NextOutJumpAction.class); 641 642 643 private static PreviousOutJumpAction previousAction = (PreviousOutJumpAction)PreviousOutJumpAction.get (PreviousOutJumpAction.class); 644 645 646 private JumpActionPerformer jumpPerformer = new JumpActionPerformer(); 647 private ActionPerformer copyActionPerformer = null; 648 CallbackSystemAction csa; 649 650 private HashMap listeners = new HashMap (); 651 652 653 JPopupMenu jPopup; 654 private JMenuItem selectAllItem; 655 private JMenuItem findNextItem; 656 private JMenuItem clearItem; 657 private JMenuItem redirItem; 658 private JMenuItem discardItem; 659 private JMenuItem discardAllItem; 660 661 private TermListener listener; 662 private TermInputListener input_listener; 663 ActiveTerm term; 664 665 private boolean redirection = false; 666 private int tabSize; 667 668 private ActiveRegion currentHyperlink = null; 669 private ActiveRegion activeHyperlink = null; 671 673 public OutTermPane() { 674 this (null); 675 } 676 677 678 679 public OutTermPane(OutputTabInner tab) { 680 681 this.tab = tab; 682 683 listener = new TermListener() { 684 public void sizeChanged(Dimension cells, Dimension pixels) { 685 } 687 }; 688 689 term = new ActiveTerm (); 690 691 updateNextPrevActions(); 692 693 outputSettings ().addPropertyChangeListener (this); 694 695 term.addListener(listener); 696 setReadWrite( false ); 697 term.setHistorySize( outputSettings().getHistorySize() ); 698 term.pushStream(new LineDiscipline()); 699 if ( tab != null ) { 700 input_listener = new TIListener( tab ); 701 term.addInputListener(input_listener); 702 } 703 term.setClickToType(true); 704 term.setAutoCopy( false ); 705 term.setScrollOnOutput( false ); 706 if (tab != null) 707 term.getAccessibleContext().setAccessibleName(tab.getName()); 708 709 writer = new TermOutputWriter (term); 710 711 term.setWordDelineator(new WordDelineator() { 712 public int charClass(char c) { 713 if (Character.isJavaIdentifierPart(c)) 714 return 1; 715 else 716 return 0; 717 } 718 } ); 719 720 setLayout(new BorderLayout()); 721 add( term ); 722 723 724 term.setActionListener(new ActiveTermListener() { 725 public void action(ActiveRegion r, InputEvent e) { 726 if ( r.end.equals( new Coord() ) ) { 727 return; 729 } 730 731 if ( e instanceof MouseEvent ) { 732 736 if (r.parent() == term.regionManager().root()) { 737 } else { 739 r = r.parent(); 740 } 741 742 gotoHyperlink(r); 743 activateHyperlink(true); 744 } 745 } 746 } ); 747 748 term.setKeyStrokeSet(getCommonKeyStrokeSet()); 749 751 term.getCanvas().addMouseListener(new MouseUtils.PopupMouseAdapter() { 752 public void showPopup(MouseEvent mevt) { 753 if (jPopup == null) { 754 createPopupMenu(); 755 } 756 updateCopyCutAction(); 758 759 jPopup.show(term, mevt.getX(), mevt.getY()); 760 } 761 }); 762 763 term.addPropertyChangeListener (new PropertyChangeListener () { 764 public void propertyChange(PropertyChangeEvent evt) { 765 if ( "selectionExtent".equals( evt.getPropertyName() )) { 766 updateCopyCutAction(); 767 } 768 } 769 }); 770 771 term.getCanvas().addKeyListener( new KeyAdapter() { 773 774 public void keyPressed(KeyEvent e) { 775 776 switch (e.getKeyCode()) { 777 case KeyEvent.VK_ENTER: 778 case KeyEvent.VK_SPACE: 779 e.consume(); 784 activateHyperlink(true); 785 break; 786 787 case KeyEvent.VK_T: 788 if (e.getModifiers() == (Event.CTRL_MASK | 789 Event.SHIFT_MASK) ) { 790 prevHyperlink(); 792 e.consume(); 793 } else if (e.getModifiers() == Event.CTRL_MASK) { 794 linkOnStart = false; 796 nextHyperlink(); 797 e.consume(); 798 } 799 break; 800 801 case KeyEvent.VK_A: 802 if ( e.getModifiers() == Event.CTRL_MASK ) { 803 selectAll(); 804 } 805 break; 806 case KeyEvent.VK_F3: 807 if ( e.getModifiers() == 0 ) { 808 findNextPattern(); 809 } 810 break; 811 } 812 } 813 814 }); 815 816 setSettings (); 817 getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put( 818 KeyStroke.getKeyStroke(KeyEvent.VK_F10, KeyEvent.SHIFT_DOWN_MASK), 819 "popup"); getActionMap().put("popup", new PopupAction()); 821 } 822 823 public void requestFocus() { 824 super.requestFocus(); 825 term.requestFocus(); 826 activateLater(); 827 } 828 829 public boolean requestFocusInWindow() { 830 super.requestFocusInWindow(); 831 boolean result = term.requestFocusInWindow(); 832 if (result) { 833 activateLater(); 834 } 835 return result; 836 } 837 838 841 private void activateLater() { 842 SwingUtilities.invokeLater (new Runnable () { 843 public void run() { 844 Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); 846 if (c == OutTermPane.this || OutTermPane.this.isAncestorOf(c)) { 847 activated(); 848 } 849 } 850 }); 851 } 852 853 854 private class PopupAction extends AbstractAction { 855 public void actionPerformed (ActionEvent ae) { 856 if (jPopup == null) { 857 createPopupMenu(); 858 } 859 updateCopyCutAction(); 861 jPopup.show((JComponent ) getTerm(), 0, 0); 862 } 863 } 864 865 public Term getTerm() { 866 return term; 867 } 868 869 private boolean isFindNextEnabled() { 870 return findNextEnabled; 871 } 872 873 private void setFindNextEnabled(boolean val) { 874 findNextEnabled = val; 875 if (findNextItem != null) { 876 findNextItem.setEnabled (val); 877 } 878 } 879 880 882 public OutputWriter getOut () { 883 return writer; 884 } 885 886 private void createPopupMenu() { 887 jPopup = SystemAction.createPopupMenu( new SystemAction[] {copy, find} ); 888 889 if ( tab == null ) 890 redirection = false; 892 else 893 redirection = outputSettings().isRedirection(); 894 895 findNextItem = new JMenuItem (NbBundle.getBundle(OutTermPane.class).getString("CTL_FindNext")); 896 findNextItem.addActionListener(this); 897 findNextItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_F3, 0 ) ); 898 findNextItem.setEnabled (isFindNextEnabled()); 899 jPopup.add(findNextItem); 900 901 selectAllItem = new JMenuItem (NbBundle.getBundle(OutTermPane.class).getString("CTL_SelectAll")); 902 selectAllItem.addActionListener(this); 903 selectAllItem.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_A, Event.CTRL_MASK ) ); 904 jPopup.add(selectAllItem); 905 jPopup.addSeparator(); 906 clearItem = new JMenuItem (NbBundle.getBundle(OutTermPane.class).getString("CTL_Clear")); 908 clearItem.addActionListener(this); 909 jPopup.add(clearItem); 910 redirItem = new JMenuItem (); 912 redirItem.addActionListener(this); 913 redirItem.setToolTipText(NbBundle.getBundle(OutputTabInner.class).getString("HINT_Redirect_Tab")); 914 if ( tab != null ) { 915 checkRedirItem(); 916 jPopup.addSeparator(); 917 jPopup.add(redirItem); 918 } 919 jPopup.addSeparator(); 920 discardItem = new JMenuItem (NbBundle.getBundle(OutTermPane.class).getString("LBL_Discard")); 922 discardItem.addActionListener(this); 923 jPopup.add(discardItem); 924 discardAllItem = new JMenuItem (NbBundle.getBundle(OutTermPane.class).getString("LBL_DiscardAll")); 926 discardAllItem.addActionListener(this); 927 jPopup.add(discardAllItem); 928 } 929 930 void updateNextPrevActions() { 931 932 935 if (firstHyperlink() != null) { 936 nextAction.setActionPerformer(jumpPerformer); 937 previousAction.setActionPerformer(jumpPerformer); 938 } else { 939 if (nextAction.getActionPerformer() == jumpPerformer) { 942 nextAction.setActionPerformer(null); 943 } 944 if (previousAction.getActionPerformer() == jumpPerformer) { 945 previousAction.setActionPerformer(null); 946 } 947 } 948 } 949 950 boolean updateCopyCutAction () { 951 cut.setActionPerformer( null ); 952 delete.setActionPerformer( null ); 953 find.setActionPerformer( new FindActionPerformer() ); 954 boolean ret; 955 if ( term.getSelectedText() != null && term.getSelectedText().length() > 0 ) { 956 copy.setActionPerformer( getCopyActionPerformer() ); 957 ret = true; 958 } 959 else { 960 copy.setActionPerformer( null ); 961 ret = false; 962 } 963 updatePasteAction(); 964 return ret; 965 } 966 967 private class FindActionPerformer implements ActionPerformer { 968 public void performAction(final SystemAction action) { 969 invokeLater(new Runnable () { 971 public void run() { 972 FindDialogPanel findDialog = FindDialogPanel.showFindDialog(); 973 if ( findDialog.isAccepted() ) { 974 String pattern = findDialog.getPattern(); 975 if ( pattern != null && pattern.length() > 0 ) 976 findPattern( 977 pattern, 978 ! findDialog.isBackwardSearch(), 979 findDialog.isMatchCase(), 980 findDialog.isWholeWordsOnly() 981 ); 982 } 983 } 984 }); 985 } 986 } 987 988 990 private void findPattern(String pattern, boolean forward, boolean matchcase, boolean wholewords) { 991 int lastFindRow = 0; 992 int lastFindCol = 0; 993 boolean doClearSel = false; 994 if ( term.getSelectionExtent() != null ) { 995 doClearSel = true; 996 lastFindRow = term.getSelectionExtent().begin.row; 997 lastFindCol = term.getSelectionExtent().begin.col; 998 } 999 else if ( ! forward ) { 1000 lastFindRow = term.getCursorCoord().row; 1001 lastFindCol = term.getCursorCoord().col; 1002 } 1003 int row = lastFindRow; 1004 int bcol; 1005 int ecol; 1006 int found = -1; 1007 int n = term.getCursorRow(); 1008 while ( found == -1 && row <= n && row >= 0) { 1009 String s = term.getRowText( row ); 1010 if ( row == lastFindRow ) { 1011 if ( forward ) { 1012 ecol = s.length(); 1013 if ( lastFindCol + 1 < ecol ) 1014 bcol = lastFindCol + 1; 1015 else 1016 bcol = ecol; 1017 } 1018 else { 1019 bcol = 0; 1020 if ( lastFindCol + pattern.length() - 1 < s.length() ) 1021 ecol = lastFindCol + pattern.length() - 1; 1022 else 1023 ecol = 0; } 1025 } 1026 else { 1027 bcol = 0; 1028 ecol = s.length(); 1029 } 1030 if ( s.length() > 0 ) 1031 found = nextIndexOf( s, bcol, ecol, pattern, forward, matchcase, wholewords ); 1032 if ( found == -1 ) { 1033 if ( forward ) 1034 row ++; 1035 else 1036 row --; 1037 } 1038 } 1039 if ( found > -1 ) { 1040 Coord beginC = Coord.make( row, found ); 1042 Extent selExt = new Extent( beginC, Coord.make( row, found + pattern.length() - 1 ) ); 1043 term.setSelectionExtent( selExt ); 1044 term.possiblyNormalize( beginC ); 1045 setFindNextEnabled(true); 1046 } 1047 else if ( doClearSel ) 1048 term.clearSelection(); 1049 } 1050 1051 1053 private void findNextPattern() { 1054 String pattern = FindDialogPanel.getPattern(); 1055 if ( pattern != null && pattern.length() > 0 ) 1056 findPattern( 1057 pattern, 1058 ! FindDialogPanel.isBackwardSearch(), 1059 FindDialogPanel.isMatchCase(), 1060 FindDialogPanel.isWholeWordsOnly() 1061 ); 1062 } 1063 1064 1067 private int nextIndexOf(String line, int bcol, int ecol, String pattern, boolean forward, 1068 boolean matchcase, boolean wholewords) { 1069 int found = -1; 1070 if ( ! matchcase ) { 1071 pattern = pattern.toLowerCase(); 1072 line = line.toLowerCase(); 1073 } 1074 int len = pattern.length(); 1075 while ( found == -1 && bcol < ecol ) { 1076 if ( forward ) 1077 found = line.substring( bcol, ecol ).indexOf( pattern ); 1078 else 1079 found = line.substring( bcol, ecol ).lastIndexOf( pattern ); 1080 if ( found > -1 ) { 1081 found = found + bcol; 1082 if ( wholewords ) { 1083 if ( ( found > 0 && Character.isUnicodeIdentifierPart( line.charAt( found - 1 ) ) ) || 1084 ( found + len < line.length() 1085 && Character.isUnicodeIdentifierPart( line.charAt( found + len ) ) ) ) 1086 { 1087 if ( forward ) { 1088 bcol = found + len; 1089 } 1090 else 1091 ecol = found; 1092 found = -1; 1093 } 1094 } 1095 } 1096 else 1097 break; 1098 } 1099 1100 return found; 1101 } 1102 1103 private void updatePasteAction () { 1104 if ( term.isReadOnly() ) { 1105 paste.setPasteTypes (null); 1106 return; 1107 } 1108 1109 Clipboard clipboard = getClipboard(); 1110 Transferable contents = clipboard.getContents( this ); 1111 if (contents == null) { 1112 paste.setPasteTypes (null); 1113 return; 1114 } 1115 1116 if (!contents.isDataFlavorSupported(DataFlavor.stringFlavor)) { 1117 paste.setPasteTypes (null); 1118 return; 1119 } 1120 1121 paste.setPasteTypes( new PasteType[] { 1122 new PasteType() { 1123 public Transferable paste() throws IOException { 1124 term.paste(); 1125 return null; 1126 } 1127 } 1128 }); 1129 } 1130 1131 private ActionPerformer getCopyActionPerformer() { 1132 if ( copyActionPerformer == null ) 1133 copyActionPerformer = new CopyActionPerformer( term ); 1134 return copyActionPerformer; 1135 } 1136 1137 private static Clipboard getClipboard() { 1138 Clipboard c = (java.awt.datatransfer.Clipboard ) 1139 org.openide.util.Lookup.getDefault().lookup(java.awt.datatransfer.Clipboard .class); 1140 if (c == null) { 1141 c = java.awt.Toolkit.getDefaultToolkit().getSystemClipboard(); 1142 } 1143 return c; 1144 } 1145 1146 1147 1148 1149 1150 1180 private void activateHyperlink(boolean doAction) { 1181 if (currentHyperlink != null) { 1182 invokeJumpListener(currentHyperlink.begin, doAction ); 1183 1184 if ( activeHyperlink != null ) { 1186 int brow = activeHyperlink.begin.row; 1187 int erow = activeHyperlink.end.row; 1188 for (int r = brow; r <= erow; r++) 1189 term.setRowGlyph(r, 0, 0); 1190 } 1191 1192 activeHyperlink = currentHyperlink; 1193 1194 if ( activeHyperlink != null ) { 1196 int brow = activeHyperlink.begin.row; 1197 int erow = activeHyperlink.end.row; 1198 for (int r = brow; r <= erow; r++) 1199 term.setRowGlyph(r, 0, 58+1); term.flush(); 1201 } 1202 } 1203 } 1204 1205 private ActiveRegion firstHyperlink() { 1206 ActiveRegion ar = term.regionManager().root(); 1207 if (ar != null) 1208 ar = ar.firstChild(); 1209 return ar; 1210 } 1211 1212 private ActiveRegion lastHyperlink() { 1213 ActiveRegion ar = term.regionManager().root(); 1214 if (ar != null) 1215 ar = ar.lastChild(); 1216 return ar; 1217 } 1218 1219 private boolean next_wrap_warned = false; 1220 private boolean prev_wrap_warned = false; 1221 private boolean linkOnStart = false; 1222 1223 private boolean nextHyperlink() { 1224 return nextHyperlink( false ); 1225 } 1226 1227 private boolean nextHyperlink(boolean forAction) { 1228 ActiveRegion ar = currentHyperlink; 1229 if (ar == null) { 1230 ar = firstHyperlink(); 1231 } else if ( forAction && linkOnStart ) { 1232 ar = firstHyperlink(); 1233 } else { 1234 prev_wrap_warned = false; 1235 ar = ar.getNextSibling(); 1236 if (ar == null) { 1237 if (next_wrap_warned) { 1238 next_wrap_warned = false; 1239 ar = firstHyperlink(); 1240 } else { 1241 String msg = NbBundle.getBundle(OutputTabInner.class). 1242 getString("MSG_AtLastError"); 1243 org.openide.awt.StatusDisplayer.getDefault().setStatusText(msg); 1244 next_wrap_warned = true; 1245 return false; 1246 } 1247 } 1248 } 1249 gotoHyperlink(ar); 1250 return true; 1251 } 1252 1253 private boolean prevHyperlink() { 1254 ActiveRegion ar = currentHyperlink; 1255 if (ar == null) { 1256 ar = lastHyperlink(); 1257 } else { 1258 next_wrap_warned = false; 1259 ar = ar.getPreviousSibling(); 1260 if (ar == null) { 1261 if (prev_wrap_warned) { 1262 prev_wrap_warned = false; 1263 ar = lastHyperlink(); 1264 } else { 1265 String msg = NbBundle.getBundle(OutputTabInner.class). 1266 getString("MSG_AtFirstError"); 1267 org.openide.awt.StatusDisplayer.getDefault().setStatusText(msg); 1268 prev_wrap_warned = true; 1269 return false; 1270 } 1271 } 1272 } 1273 gotoHyperlink(ar); 1274 return true; 1275 } 1276 1277 private void gotoHyperlink(ActiveRegion ar) { 1278 if (ar == null) 1279 return; 1280 1281 ActiveRegion link = ar.firstChild(); 1283 if (link == null) { 1284 link = ar; 1286 } 1287 1288 currentHyperlink = ar; 1289 term.setSelectionExtent(link.getExtent()); 1290 term.possiblyNormalize(ar); 1291 } 1292 1293 1294 private void invokeJumpListener( Coord index, boolean doAction ) { 1295 1297 1300 1301 1304 OutputListener olistener = (OutputListener)listeners.get(index); 1305 String str = term.textWithin(currentHyperlink.begin, 1306 currentHyperlink.end); 1307 linkOnStart = false; 1308 if (olistener != null) { 1309 if ( doAction ) 1310 olistener.outputLineAction( new OutputEventImpl(InputOutput.NULL, str )); 1311 else 1312 olistener.outputLineSelected( new OutputEventImpl(InputOutput.NULL, str )); 1313 } 1314 } 1315 1316 1317 private static final class OutputEventImpl extends OutputEvent { 1318 private String txt; 1319 1320 static final long serialVersionUID =-437312125483471519L; 1321 1322 public OutputEventImpl(InputOutput src, String txt) { 1323 super(src); 1324 this.txt = txt; 1325 } 1326 1327 1330 public String getLine () { 1331 return txt; } 1334 } 1335 1336 1337 1340 class TermOutputWriter extends OutputWriter { 1341 ActiveTerm aterm = null; 1342 boolean timerSet = false; 1343 Boolean timerMode = null; 1344 boolean redirOpened = false; 1345 FileWriter redirWriter = null; 1346 private ActiveRegion region = null; 1347 1348 TermOutputWriter(ActiveTerm term) { 1349 super(new OutputStreamWriter (new NullOutputStream())); 1350 aterm = term; 1351 setPageMode (false); 1352 aterm.setRefreshEnabled(false); 1353 if ( tab != null ) 1354 redirection = outputSettings ().isRedirection(); 1355 checkRedirItem(); 1356 if ( redirection ) 1357 redirOpen(); 1358 } 1359 1360 1361 public void reset() throws java.io.IOException { 1362 invokeNow(new Runnable () { 1364 public void run() { 1365 doClear(); 1366 aterm.setRefreshEnabled(false); 1367 resetRegion (); 1368 prev_wrap_warned = false; 1369 next_wrap_warned = false; 1370 } 1371 }); 1372 } 1373 1374 public void println(String str, final OutputListener outputListener) throws java.io.IOException { 1375 final String strCopy = str; 1376 1377 ensureOpen (); 1379 invokeNow(new Runnable () { 1380 public void run() { 1381 historySizeKeeper (); 1382 1383 if ( outputListener != null ) { 1384 1385 1394 1404 createRegion(strCopy, true); 1405 registerListener(region ,outputListener); 1406 } else 1407 appendText(strCopy,false); 1408 1409 printEOL (); 1410 } 1411 }); 1412 } 1413 1414 public void println() { 1415 ensureOpen (); 1417 invokeNow(new Runnable () { 1418 public void run() { 1419 printEOL (); 1420 } 1421 }); 1422 } 1423 1424 public void write(char cbuf[], final int off, final int len) { 1425 ensureOpen (); 1427 final char cbufCopy[] = safe_way? new char[cbuf.length]: cbuf; 1428 if (safe_way) 1429 System.arraycopy(cbuf, 0, cbufCopy, 0, cbuf.length); 1430 invokeNow(new Runnable () { 1431 public void run() { 1432 appendText(new String (cbufCopy,off,len), !isTimerMode ()); 1433 } 1434 }); 1435 } 1436 1437 public void write(final int ch) { 1438 invokeNow(new Runnable () { 1440 public void run() { 1441 write ( new char[]{(char)ch}, 0, 1); 1442 } 1443 }); 1444 } 1445 1446 public void write(String str, int off, final int len) { 1447 final char[] chars = new char [len]; 1449 str.getChars(off,off+len,chars,0); 1450 invokeNow(new Runnable () { 1451 public void run() { 1452 write(chars,0,len); 1453 } 1454 }); 1455 } 1456 1457 public void flush() { 1458 invokeNow(new Runnable () { 1460 public void run() { 1461 aterm.flush(); 1462 if ( redirWriter != null ) 1463 try { 1464 redirWriter.flush(); 1465 } catch (IOException e) { 1466 } 1468 } 1469 }); 1470 } 1471 1472 public void close() { 1473 invokeNow(new Runnable () { 1475 public void run() { 1476 if ( redirOpened ) 1477 redirClose(); 1478 } 1479 }); 1480 } 1481 1482 1483 1484 private void redirOpen() { 1485 File redirFile = null; 1486 try { 1487 File redirDirFile = outputSettings ().getDirectory(); 1488 1489 String name = ""; 1490 if (tab != null) { 1491 name = tab.getName(); 1492 int ispace = name.indexOf(' '); 1493 if (ispace > 0) 1494 name = name.substring( 0, ispace ); 1495 } 1496 name = name.replace(File.separatorChar, '_'); 1497 name = name + REDIR_EXT; 1498 redirFile = new File (redirDirFile, name); 1499 1500 redirFile.createNewFile(); 1501 redirWriter = new FileWriter (redirFile.getAbsolutePath(),true); 1502 1503 redirOpened = true; 1504 } catch (Exception e) { 1505 ErrorManager.getDefault().annotate(e, ErrorManager.UNKNOWN, "Redir file: " + redirFile, null, null, null); ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 1507 } 1508 } 1509 1510 private void redirClose() { 1511 if ( redirWriter != null ) 1512 try { 1513 redirWriter.close(); 1514 redirWriter = null; 1515 } catch (IOException e) { 1516 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 1517 } 1518 } 1519 1520 private void redirPrint(char[] chars,int offs, int len) { 1521 if ( redirWriter == null ) 1522 redirOpen(); 1523 if (redirWriter == null) return; 1524 try { 1525 redirWriter.write(chars, offs, len); 1526 } catch (IOException e) { 1527 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 1528 } 1529 } 1530 1531 private void redirPrint(String str) { 1532 if ( redirWriter == null ) 1533 redirOpen(); 1534 if (redirWriter == null) return; 1535 try { 1536 redirWriter.write(str); 1537 } catch (IOException e) { 1538 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 1539 } 1540 } 1541 1542 1543 private ActiveRegion createRegion(String str, boolean hyperlink) { 1544 beginRegion (str, hyperlink); 1545 return endRegion (null); 1546 } 1547 1548 private ActiveRegion beginRegion(String str, boolean hyperlink) { 1549 resetRegion (); 1550 setPageMode (true); 1551 Coord beginCoord = Coord.make(aterm.getCursorCoord().row, 0 ); 1552 1553 try { 1554 region = aterm.regionManager().beginRegion(beginCoord); 1555 } catch (RegionException x) { 1556 return null; 1557 } 1558 1560 region.setFeedbackEnabled(false); 1561 region.setSelectable(false); 1563 1564 if (hyperlink) { 1565 aterm.setAttribute( getLinkAttr() ); aterm.setAttribute(4); } 1568 1569 if (str != null) 1570 appendText(str, false); 1571 1572 return region; 1573 } 1574 1575 private ActiveRegion endRegion(String str) { 1576 aterm.setAttribute(0); if (str != null) 1578 appendText(str, false); 1579 1580 aterm.endRegion(); 1581 1582 updateNextPrevActions(); 1583 return region; 1584 } 1585 1586 private void firstHalf(String str) { 1587 setPageMode (true); 1588 Coord beginCoord = Coord.make(aterm.getCursorCoord().row, 0 ); 1589 1590 try { 1592 region = aterm.regionManager().beginRegion(beginCoord); 1593 } catch (RegionException x) { 1594 return; 1595 } 1596 1597 region.setFeedbackEnabled(false); 1598 region.setSelectable(false); 1599 1600 1601 ActiveRegion link_region; 1603 try { 1604 link_region = aterm.regionManager().beginRegion(beginCoord); 1605 } catch (RegionException x) { 1606 return; 1607 } 1608 1609 aterm.setAttribute( getLinkAttr() ); aterm.setAttribute(4); 1612 appendText(str, false); 1613 1614 aterm.setAttribute(0); 1616 aterm.endRegion(); 1617 1618 } 1621 1622 private void secondHalf(String str) { 1623 appendText(str, false); 1624 1625 aterm.endRegion(); 1626 1627 updateNextPrevActions(); 1628 } 1629 1630 1637 private boolean isTimerMode () { 1638 if (timerMode == null) { 1639 String tempStr = System.getProperty("org.netbeans.core.output.OutputTabInner.timerMode"); 1640 timerMode = (tempStr != null && tempStr.equalsIgnoreCase("false")) ? Boolean.FALSE : Boolean.TRUE; } 1642 1643 return timerMode.booleanValue(); 1644 } 1645 1646 1653 private void repaintTimer() { 1654 if ( ! timerSet ) { 1655 timerSet = true; 1656 org.openide.util.RequestProcessor.getDefault().post( new Runnable () { 1657 public void run() { 1658 flush(); 1659 timerSet = false; 1660 } 1661 }, 1662 120); 1663 } 1664 } 1665 1666 1676 private void setPageMode (boolean pageMode) { 1677 if (isPageMode ()) return; 1678 aterm.setAnchored (pageMode); 1679 } 1680 1681 private boolean isPageMode () { 1682 return aterm.isAnchored (); 1683 } 1684 1685 1689 private void historySizeKeeper () { 1690 if (!isPageMode ()) return; 1691 1693 if (aterm.getHistoryBuffSize () - aterm.getHistorySize () > 0) { 1694 try { 1695 reset (); 1696 } catch (Exception exc) { 1697 } 1699 } 1700 1701 } 1702 1703 private void resetRegion () { 1704 if (region != null) { 1705 aterm.endRegion(); 1706 region = null; 1707 } 1708 } 1709 1710 private void registerListener (ActiveRegion regRegion, OutputListener outpList) { 1711 if (regRegion != null && outpList != null) 1712 listeners.put( regRegion.begin, outpList ); 1713 } 1714 1715 private void printEOL () { 1716 appendText("\n",!isTimerMode ()); } 1718 1719 1723 private void appendText (String str, boolean repaint) { 1724 if (isTimerMode ()) { 1725 1729 if ( redirection ) 1730 redirPrint(str); 1731 1732 char[] cs = str.toCharArray(); 1733 aterm.putChars(cs, 0, cs.length); 1734 repaintTimer(); 1735 return; 1736 } 1737 1738 char[] tmp = new char[str.length()]; 1739 str.getChars(0, str.length(), tmp, 0); 1740 1741 appendChars(tmp,0, str.length(), repaint); 1742 } 1743 1744 private void appendChars(char[] chars,int offs, int len, boolean repaint) { 1745 if (isTimerMode ()) { 1746 appendText (new String (chars, offs, len), repaint); 1747 return; 1748 } 1749 1750 if ( redirection ) 1751 redirPrint(chars, offs, len); 1752 1753 if (!repaint && aterm.isRefreshEnabled()) { 1754 1759 aterm.setRefreshEnabled(false); 1760 aterm.putChars(chars, offs, len); 1761 aterm.setRefreshEnabled(true); 1762 } else aterm.putChars(chars, offs, len); 1763 } 1764 } 1765 1766 final class JumpActionPerformer implements ActionPerformer { 1767 1768 1769 public void performAction(final SystemAction action) { 1770 invokeLater(new Runnable () { 1771 public void run() { 1772 1773 if (action instanceof NextOutJumpAction) { 1774 if (nextHyperlink(true)) 1776 activateHyperlink(true); 1777 } 1778 1779 if (action instanceof PreviousOutJumpAction) { 1780 if (prevHyperlink()) 1782 activateHyperlink(true); 1783 } 1784 1785 updateNextPrevActions(); 1786 } 1787 }); 1788 } 1789 } 1790 1791 static class CopyActionPerformer extends Object implements 1792 org.openide.util.actions.ActionPerformer { 1793 1794 ActiveTerm at; 1795 1796 public CopyActionPerformer (ActiveTerm at) { 1797 this.at = at; 1798 } 1799 1800 1801 public void performAction(org.openide.util.actions.SystemAction action) { 1802 invokeLater(new Runnable () { 1803 public void run() { 1804 at.copy(); 1805 } 1806 }); 1807 } 1808 } 1809 1810 private static class TIListener implements TermInputListener { 1811 1812 private OutputTabInner tab; 1813 1814 public TIListener(OutputTabInner tab) { 1815 this.tab = tab; 1816 } 1817 1818 public void sendChar(char c) { 1819 try { 1820 tab.inWriter.write(c); 1821 tab.inWriter.flush(); 1822 } catch (Exception x) { 1823 } 1825 } 1826 public void sendChars(char[] c, int offset, int n) { 1827 try { 1828 tab.inWriter.write(c, offset, n); 1829 tab.inWriter.flush(); 1830 } catch (Exception x) { 1831 } 1833 } 1834 } 1835 1836 1837 public void activated() { 1838 updateCopyCutAction (); 1839 if (csa == null) { 1840 try { 1841 Class popup = Class.forName("org.openide.actions.PopupAction"); csa = (CallbackSystemAction) CallbackSystemAction.get(popup); 1844 } catch (ClassNotFoundException e) { 1845 Error err = new NoClassDefFoundError (); 1846 ErrorManager.getDefault().annotate(err, e); 1847 throw err; 1848 } 1849 } 1850 csa.setActionPerformer(this); 1851 setFindNextEnabled( FindDialogPanel.getPattern() != null ); 1852 } 1853 1854 1855 public void deactivated() { 1856 if (csa != null && this.equals( csa.getActionPerformer() ) ) { 1857 csa.setActionPerformer(null); 1858 } 1859 } 1860 1861 public void focusGained(FocusEvent ev) { 1862 } 1864 1865 public void focusLost(FocusEvent ev) { 1866 } 1868 1869 1872 public void performAction(SystemAction action) { 1873 if (! (action instanceof org.openide.actions.PopupAction) ) 1874 return; 1875 Mutex.EVENT.readAccess( new Runnable () { 1876 public void run() { 1877 Coord xy = null; 1878 1879 if ( ! term.isReadOnly() && term.isCoordVisible(term.getCursorCoord()) ) { 1880 xy = term.getCursorCoord(); 1881 } 1882 else if ( term.getSelectionExtent() != null ) { 1883 if ( term.isCoordVisible(term.getSelectionExtent().begin )) { 1884 xy = term.getSelectionExtent().begin; 1885 } 1886 else if ( term.isCoordVisible(term.getSelectionExtent().end )) { 1887 xy = term.getSelectionExtent().end; 1888 } 1889 } 1890 1891 if ( xy == null && currentHyperlink != null ) { 1892 if ( term.isCoordVisible(currentHyperlink.begin )) { 1893 xy = currentHyperlink.begin; 1894 } 1895 else if ( term.isCoordVisible(currentHyperlink.end )) { 1896 xy = currentHyperlink.end; 1897 } 1898 } 1899 1900 Point p = null; 1901 if ( xy == null ) 1902 p = new Point( 0, 0 ); 1903 else 1904 p = term.toPixel( xy ); 1905 1906 if (p == null) { 1907 return; 1908 } 1909 if (jPopup == null) { 1910 createPopupMenu(); 1911 } 1912 jPopup.show(term, p.x, p.y); 1913 } 1914 }); 1915 } 1916 1917 public void actionPerformed(java.awt.event.ActionEvent actionEvent) { 1918 if (actionEvent.getSource() == selectAllItem) { 1919 selectAll(); 1920 } 1921 else if (actionEvent.getSource() == findNextItem) { 1922 findNextPattern(); 1923 } else if (actionEvent.getSource() == clearItem) { 1924 doClear(); 1925 } else if (actionEvent.getSource() == redirItem) { 1926 redirection = !redirection; 1927 checkRedirItem(); 1928 } else if (actionEvent.getSource() == discardItem) { 1929 OutputView.findDefault().discardTab(); 1930 } else if (actionEvent.getSource() == discardAllItem) { 1931 OutputView.findDefault().discardAllTabs(); 1932 } 1933 } 1934 1935 void doClear() { 1936 term.clearHistory(); 1937 term.clear(); 1938 setHyperlinkNavigationEnabled(false); 1939 Iterator it = listeners.values().iterator(); 1940 while (it.hasNext()) { 1941 OutputListener oli = (OutputListener)it.next(); 1942 oli.outputLineCleared( new OutputEventImpl(InputOutput.NULL, null )); 1943 } 1944 listeners.clear(); 1945 activeHyperlink = null; 1946 currentHyperlink = null; 1947 updateNextPrevActions(); 1948 } 1949 1950 1951 private static OutputSettings outputSettings () { 1952 return (OutputSettings)OutputSettings.findObject (OutputSettings.class, true); 1953 } 1954 1955 1956 private boolean hyperlinkNavigationEnabled = false; 1957 1958 private void setHyperlinkNavigationEnabled(boolean hlne) { 1959 1960 if (hyperlinkNavigationEnabled == hlne) 1961 return; 1962 hyperlinkNavigationEnabled = hlne; 1963 1964 1967 if (hlne) { 1968 term.setScrollOnInput(false); 1969 term.setKeyStrokeSet(getCommonKeyStrokeSet2()); 1970 } else { 1971 term.setScrollOnInput(true); 1972 term.setKeyStrokeSet(getCommonKeyStrokeSet()); 1973 } 1974 1975 } 1976 1977 private void checkRedirItem() { 1978 if ( tab == null ) 1979 return; 1980 if ( !redirection && writer != null ) 1981 ((TermOutputWriter)writer).redirClose(); 1982 if ( redirItem == null ) 1983 return; 1984 if ( redirection ) { 1985 if (outputSettings().checkRedirectionDirExists(outputSettings().getDirectory())) { 1986 redirItem.setText(NbBundle.getBundle (OutputTabInner.class).getString ("CTL_Redirect_Off")); 1987 } else { 1988 redirection = false; 1989 } 1990 } else { 1991 redirItem.setText(NbBundle.getBundle (OutputTabInner.class).getString ("CTL_Redirect_On")); 1992 } 1993 } 1994 1995 private void checkFont() { 1996 Font font = term.getFont(); 1997 if (font != null && 1998 font.isPlain() && 1999 (font.getSize() == outputSettings ().getFontSize())) { 2000 return; 2001 } else { 2002 Font nf = new Font("Monospaced", java.awt.Font.PLAIN, outputSettings ().getFontSize()); term.setFont(nf); 2004 } 2005 } 2006 2007 private void setSettings () { 2008 checkFont(); 2009 term.setForeground( outputSettings ().getBaseForeground()); 2010 term.setBackground( outputSettings ().getBaseBackground()); 2011 term.setCustomColor(1, outputSettings().getJumpCursorBackground()); 2012 term.setHistorySize( outputSettings().getHistorySize() ); 2013 tabSize = outputSettings ().getTabSize(); 2014 term.setTabSize( tabSize ); 2015 term.setCustomColor( 0, outputSettings ().getJumpLinkForeground()); 2016 term.setHighlightColor( outputSettings ().getSelectionBackground()); 2017 } 2018 2019 public void propertyChange (PropertyChangeEvent evt) { 2020 if ( OutputSettings.PROP_REDIRECTION.equals( evt.getPropertyName() )) { 2021 if ( tab != null ) { 2022 redirection = ((Boolean )evt.getNewValue()).booleanValue(); 2023 checkRedirItem(); 2024 } 2025 } 2026 else if ( OutputSettings.PROP_DIRECTORY.equals( evt.getPropertyName() )) { 2027 if ( tab != null ) { 2028 if ( redirection && writer != null ) { 2029 ((TermOutputWriter)writer).redirClose(); 2030 if (outputSettings().getDirectory().exists()) { 2031 ((TermOutputWriter)writer).redirOpen(); 2032 } 2033 } 2034 } 2035 } 2036 else 2037 setSettings (); 2038 } 2039 2040 private void selectAll() { 2041 Extent allExt = new Extent( Coord.make(0,0), term.getCursorCoord() ); 2042 term.setSelectionExtent( allExt ); 2043 } 2044 2045 private void ensureOpen() { 2046 if (isShowing()) { 2047 return; 2048 } 2049 if (!SwingUtilities.isEventDispatchThread()) { 2053 SwingUtilities.invokeLater(new Runnable () { 2054 public void run() { 2055 _ensureOpen(); 2056 } 2057 }); 2058 } else { 2059 _ensureOpen(); 2060 } 2061 } 2062 2063 private void _ensureOpen() { 2064 if (tab != null) { 2065 tab.ensureOpen(); 2066 } 2067 } 2068 2069 private ArrayList runnables = new ArrayList (); 2070 private boolean runningRunnables; 2071 private Object syncObject = new Object (); 2072 2073 2085 private void invokeNow(final Runnable runnable) { 2086 if (SwingUtilities.isEventDispatchThread()) { 2087 runnable.run(); 2088 } else { 2089 if (safe_way) { 2090 synchronized ( syncObject ) { 2091 if (runningRunnables) { 2092 try { 2093 syncObject.wait (500); 2094 } catch (InterruptedException ex) { 2095 } 2096 } 2097 2098 runnables.add( runnable ); 2099 if (runnables.size () > 50) { 2100 try { 2101 syncObject.wait (500); 2102 } catch (InterruptedException ex) { 2103 } 2104 } 2105 if ( runnables.size() == 1 ) 2106 SwingUtilities.invokeLater( this ); 2107 } 2108 } 2109 else { 2110 try { 2111 SwingUtilities.invokeAndWait(runnable); 2112 } catch (Exception x) { 2113 ; 2114 } 2115 } 2116 } 2117 } 2118 2119 public void run () { 2120 ArrayList torun; 2121 synchronized ( syncObject ) { 2122 runningRunnables = true; 2123 torun = (ArrayList )runnables.clone(); 2124 runnables = new ArrayList (); 2125 } 2126 Iterator it = torun.iterator(); 2127 while ( it.hasNext() ) 2128 ((Runnable )(it.next())).run(); 2129 synchronized ( syncObject ) { 2130 runningRunnables = false; 2131 syncObject.notifyAll(); 2132 } 2133 } 2134 2135 private int getLinkAttr() { 2136 return 50; 2138 } 2139 2140 void setReadWrite( boolean rw ) { 2141 term.setCursorVisible ( rw ); 2142 term.setReadOnly ( !rw ); 2143 } 2144 } 2145 2146 final static private boolean safe_way = true; 2147 2148 2149 2150 2151 private static void invokeLater(Runnable runnable) { 2152 if (SwingUtilities.isEventDispatchThread()) { 2153 runnable.run(); 2154 } else { 2155 SwingUtilities.invokeLater(runnable); 2156 } 2157 } 2158 2159 2167 2168} 2169 | Popular Tags |