KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > core > output > OutputView


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 package org.netbeans.core.output;
21
22 import java.util.WeakHashMap JavaDoc;
23 import java.util.HashSet JavaDoc;
24 import java.io.PipedWriter JavaDoc;
25
26 import java.awt.*;
27 import java.awt.event.*;
28 import java.awt.datatransfer.*;
29 import java.beans.PropertyChangeListener JavaDoc;
30 import java.beans.PropertyChangeEvent JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Set JavaDoc;
33 import javax.swing.AbstractAction JavaDoc;
34
35 import javax.swing.JPopupMenu JavaDoc;
36 import javax.swing.JMenuItem JavaDoc;
37 import javax.swing.JTabbedPane JavaDoc;
38 import javax.swing.KeyStroke JavaDoc;
39 import javax.swing.SwingUtilities JavaDoc;
40
41 import org.openide.ErrorManager;
42 import org.openide.windows.*;
43 import org.openide.util.NbBundle;
44 import org.openide.util.Mutex;
45 import org.openide.util.Utilities;
46 import org.openide.util.WeakSet;
47 import org.openide.util.datatransfer.*;
48 import org.openide.nodes.Node;
49
50 import org.netbeans.lib.terminalemulator.*;
51
52 /**
53  * TopComponent for output tabs. It handles output in new winsts implementation.
54  *
55  * @author Marek Slama
56  *
57  */

58
59 public class OutputView extends TopComponent implements PropertyChangeListener JavaDoc, ActionListener {
60
61
62     private static final boolean DEBUG = false;
63     
64     public static final String JavaDoc ICON_RESOURCE =
65         "/org/netbeans/core/resources/frames/output.gif"; // NOI18N
66

67     /** If true, the error output is separated from the normal output */
68
69     /** Mapping of string:OutputTabInner */
70     static final Map JavaDoc ioCache = new WeakHashMap JavaDoc(7);
71
72     /** Singleton instances of the standard output tabs */
73     private static OutputTabInner standard;
74     
75     private static final long serialVersionUID = 3276523892250080205L;
76     
77     private static Factory factory;
78     
79     /** Singleton instance */
80     private static OutputView DEFAULT;
81     
82     private JTabbedPane JavaDoc tabbedPane;
83     
84     /** Set of opened components in OutputView */
85     private Set JavaDoc openedComps = new HashSet JavaDoc(10);
86     
87     /** Set of closed components in OutputView */
88     private Set JavaDoc closedComps = new WeakSet(10);
89     
90     private String JavaDoc baseName;
91     
92     /**
93      * State machine (State _enum_ really) for recognizing java exception
94      * patterns.
95      * See comment above appendText() for general idea.
96      */

97     private static class State {
98     private final String JavaDoc name;
99     private State(String JavaDoc name) {
100         this.name = name;
101     }
102     public String JavaDoc toString() { return name; }
103
104     public static final State init = new State("init");
105     public static final State collect = new State("collect");
106     public static final State pass = new State("pass");
107     };
108
109     private static void debug(String JavaDoc s) {
110         if (!DEBUG) return;
111         s = "OutputView:"+s+"\r\n"; // NOI18N
112
try {
113             String JavaDoc dir = outputSettings().getDirectory().getAbsolutePath();
114             java.io.FileOutputStream JavaDoc fos = new java.io.FileOutputStream JavaDoc (dir + "/debug.log", true); // NOI18N
115
fos.write(s.getBytes());
116             fos.close();
117         } catch (java.io.IOException JavaDoc e) {
118             ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e);
119         }
120     }
121     
122     private OutputView () {
123         synchronized (OutputView.class) {
124             setActivatedNodes (null);
125             
126             setIcon(Utilities.loadImage("org/netbeans/core/resources/outputSettings.gif")); // NOI18N
127

128             TopComponent.getRegistry().addPropertyChangeListener(
129                 org.openide.util.WeakListener.propertyChange(this, TopComponent.getRegistry()));
130             
131             // set accessiblle description
132
getAccessibleContext ().setAccessibleName (
133                 NbBundle.getBundle (OutputView.class).getString ("ACSN_OutputWindow"));
134             getAccessibleContext ().setAccessibleDescription (
135                 NbBundle.getBundle (OutputView.class).getString ("ACSD_OutputWindow"));
136             setBorder(null);
137             setLayout(new BorderLayout());
138         }
139     }
140     
141     private OutputView (String JavaDoc name) {
142         this();
143         setName(name);
144         baseName = name;
145     }
146     
147     public void addNotify() {
148         super.addNotify();
149         TabHandlePopupListener.install();
150     }
151     
152     /** Return preferred ID */
153     protected String JavaDoc preferredID () {
154         return "output"; //NOI18N
155
}
156     
157     public void removeNotify() {
158         TabHandlePopupListener.uninstall();
159         super.removeNotify();
160     }
161     
162     public void requestActive () {
163         requestActive(true);
164     }
165     
166     public void requestActive(boolean focus) {
167         //Intentionally does not change active component if there is no
168
//inner term to focus - this will leave winsys in an inconsistent
169
//state - the active tc will be the output window but keyboard focus
170
//will be in the editor
171
if (focus) {
172             Component c = getSelectedComponent();
173             if (c != null) {
174                 if (c instanceof OutputTabInner) {
175                     boolean focused = c.requestFocusInWindow();
176                     if (focused) {
177                         super.requestActive();
178                     }
179                 }
180             }
181         }
182     }
183     
184     /* Singleton accessor. As OutputView is persistent singleton this
185      * accessor makes sure that OutputView is deserialized by window system.
186      * Uses known unique TopComponent ID "output" to get OutputView instance
187      * from window system. "output" is name of settings file defined in module layer.
188      */

189     public static synchronized OutputView findDefault () {
190         if (DEFAULT == null) {
191             TopComponent tc = WindowManager.getDefault().findTopComponent("output"); // NOI18N
192
if (tc != null) {
193                 if (tc instanceof OutputView) {
194                     DEFAULT = (OutputView) tc;
195                 } else {
196                     //Incorrect settings file?
197
IllegalStateException JavaDoc exc = new IllegalStateException JavaDoc
198                     ("Incorrect settings file. Unexpected class returned." // NOI18N
199
+ " Expected:" + OutputView.class.getName() // NOI18N
200
+ " Returned:" + tc.getClass().getName()); // NOI18N
201
ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, exc);
202                     //Fallback to accessor reserved for window system.
203
OutputView.getDefault();
204                 }
205             } else {
206                 //OutputView cannot be deserialized
207
//Fallback to accessor reserved for window system.
208
OutputView.getDefault();
209             }
210         }
211         return DEFAULT;
212     }
213     
214     /* Singleton accessor reserved for window system ONLY. Used by window system to create
215      * OutputView instance from settings file when method is given. Use <code>findDefault</code>
216      * to get correctly deserialized instance of OutputView. */

217     public static synchronized OutputView getDefault () {
218         if (DEFAULT == null) {
219             DEFAULT = new OutputView(NbBundle.getBundle(OutputView.class).getString("CTL_OutputWindow_OutputTab"));
220         }
221         return DEFAULT;
222     }
223     
224     /* Accessor reserved for window system, to discard the default instance on project switch. */
225     public static synchronized void discardDefault() {
226         if (DEFAULT != null) {
227             final OutputView last = DEFAULT;
228             DEFAULT = null;
229             Mutex.EVENT.writeAccess(new Runnable JavaDoc() {
230                 public void run() {
231                     last.clear();
232                 }
233             });
234         }
235     }
236     
237     
238     void clear() {
239         discardAllTabs();
240         closedComps.clear();
241         close();
242     }
243     
244     /** Overriden to explicitely set persistence type of OutputView
245      * to PERSISTENCE_ALWAYS */

246     public int getPersistenceType() {
247         return TopComponent.PERSISTENCE_ALWAYS;
248     }
249     
250     public static InputOutput getIO(String JavaDoc name, boolean newIO) {
251         //System.out.println("++ OutputView.getIO ENTER");
252
//Thread.dumpStack();
253
InputOutput inpo = getFactory().getIO(name, newIO);
254         /*System.out.println("++ OutputView.getIO RETURN"
255         + " c:" + ((TopComponent) inpo).getName()
256         + " [" + inpo.getClass().getName() + "]");*/

257         return inpo;
258     }
259
260     public static OutputWriter getStdOut() {
261         //System.out.println("++ OutputView.getStdOut");
262
return getFactory().getStdOut ();
263     }
264     
265     /** Reads OutputView.
266     */

267 // public void readExternal (ObjectInput oi)
268
// throws IOException, ClassNotFoundException {
269
// super.readExternal (oi);
270
// }
271

272     /** Writes OutputView. */
273 // public void writeExternal (ObjectOutput oo) throws IOException {
274
// super.writeExternal(oo);
275
// }
276

277     /** Resolve to singleton instance */
278     public Object JavaDoc readResolve() throws java.io.ObjectStreamException JavaDoc {
279         return OutputView.getDefault();
280     }
281     
282     
283     private JTabbedPane JavaDoc getTabbedPane() {
284         if(tabbedPane == null) {
285             tabbedPane = new JTabbedPane JavaDoc(JTabbedPane.TOP);
286             tabbedPane.getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
287                 KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.CTRL_DOWN_MASK),
288                 "discard"); //NOI18N
289
tabbedPane.getActionMap().put("discard", new DiscardAction());
290         }
291         return tabbedPane;
292     }
293     
294     private class DiscardAction extends AbstractAction JavaDoc {
295         public void actionPerformed (ActionEvent ae) {
296             discardTab();
297         }
298     }
299     
300     // Methods to manipulate with tabs inside OutputView.
301
/* Select component inside tab. */
302     void requestVisible (final Component c) {
303         /*System.out.println("OutputView.requestVisible ENTER"
304         + " c:" + c.getName()
305         + " th:" + Thread.currentThread().getName());
306         Thread.dumpStack();*/

307         Mutex.EVENT.readAccess(new Runnable JavaDoc() {
308             public void run() {
309                 // The output TopComponent has to be visible too.
310
OutputView.this.requestVisible();
311                 
312                 /*System.out.println("OutputView.requestVisible ENTER DELAYED"
313                 + " c:" + c.getName()
314                 + " th:" + Thread.currentThread().getName()
315                 + " isOpenedInOV(c):" + isOpenedInOV(c)
316                 + " openedComps.size:" + openedComps.size()); */

317                 if (isOpenedInOV(c) && (openedComps.size() > 1)) {
318                     /* System.out.println("OutputView.requestVisible CALL OF setSelectedComponent"
319                     + " c:" + c.getName()); */

320                     JTabbedPane JavaDoc tab = getTabbedPane();
321                     if (!c.equals(tab.getSelectedComponent())) {
322                         //System.out.println("OutputView.requestVisible CALL OF");
323
tab.setSelectedComponent(c);
324                         setActivatedNodes(((TopComponent) c).getActivatedNodes());
325                     }
326                 } /*else {
327                     System.out.println("OutputView.requestVisible NOT OPENED"
328                     + " c:" + c.getName());
329                 }*/

330                 /*System.out.println("OutputView.requestVisible LEAVE DELAYED"
331                 + " c:" + c.getName()
332                 + " th:" + Thread.currentThread().getName());*/

333             }
334         });
335     }
336     
337     /* Request focus on component in tab. */
338     void requestFocus (final Component c) {
339         Mutex.EVENT.readAccess(new Runnable JavaDoc() {
340             public void run() {
341                 // The output TopComponent has to be active when the inner tab gets focus.
342
OutputView.this.requestActive(false);
343                 if (isOpenedInOV(c)) {
344                     if (openedComps.size() > 1) {
345                         JTabbedPane JavaDoc tab = getTabbedPane();
346                         if (!c.equals(tab.getSelectedComponent())) {
347                             tab.setSelectedComponent(c);
348                             setActivatedNodes(((TopComponent) c).getActivatedNodes());
349                         }
350                     }
351                     c.requestFocusInWindow();
352                 }
353             }
354         });
355     }
356     
357     /* Returns component selected in OutputView. Returns null when OutputView is empty
358      * or when 'there is no tab selected' in JTabbedPane
359      * ie. return value from JTabbedPane.getSelectedComponent */

360     Component getSelectedComponent () {
361         if (openedComps.size() > 1) {
362             return getTabbedPane().getSelectedComponent();
363         } else if (openedComps.size() == 1) {
364             return ((Component []) openedComps.toArray(new Component[1]))[0];
365         } else {
366             return null;
367         }
368     }
369     
370     /** Returns standard output top component */
371     /*public static TopComponent getStdOutputTab() {
372         System.out.println("++ OutputView.getStdOutputTab");
373         return getFactory().getStdOutputTab();
374     }*/

375     
376     private static OutputSettings outputSettings () {
377         return (OutputSettings)OutputSettings.findObject (OutputSettings.class, true);
378     }
379     
380     /* Returns text content of output tab. This is
381     * content of terminal buffer, which is limited by
382     * history size.
383     * <p>
384     * This function is no MT-safe call it from the AWT Event Dispatch thread.
385     *
386     * @return text content of output window buffer
387     */

388     public String JavaDoc toString () {
389         return "";
390     }
391     
392     static synchronized Factory getFactory () {
393         if (factory == null) {
394             factory = new Factory();
395         }
396         return factory;
397     }
398     
399     private static synchronized void initialize () {
400         if (standard == null) {
401             // create the tab for StdOut
402
String JavaDoc name = NbBundle.getBundle(OutputView.class).getString("CTL_OutputWindow_OutputTab");
403             standard = new OutputTabInner(name);
404             // delete default behaviour of output tabs - remember even closed standard tab
405
standard.putClientProperty("PersistenceType", null); // NOI18N
406
}
407     }
408     
409     public static class Factory { //implements OutputTabProvider {
410
Factory () {
411             //debug("OutputTabInner.Factory()"); // NOI18N
412
}
413         
414         /** Print output writer.
415          * @return default system output printer
416          */

417         public OutputWriter getStdOut() {
418             //System.out.println("OutputView.Factory.getStdOut()");
419
//debug("OutputTabInner.Factory.getStdOut()"); // NOI18N
420
initialize();
421             return standard.getOut();
422         }
423         
424         /** creates new OutputWriter
425          * @param name is a name of the writer
426          * @return new OutputWriter with given name
427          */

428         public InputOutput getIO(String JavaDoc name, boolean newIO) {
429             //System.out.println("OutputView.Factory.getIO("+ name + ", " + newIO + ")");
430
//debug("OutputTabInner.Factory.getIO("+name+", "+newIO+")"); // NOI18N
431
initialize();
432             if (newIO) {
433                 //debug("..creating new"); // NOI18N
434
/*System.out.println("OutputView.Factory.getIO"
435                 + " CREATE NEW 1");*/

436                 return new OutputTabInner(name);
437             } else {
438                 InputOutput ino;
439                 synchronized(ioCache) {
440                     ino = (InputOutput)ioCache.get(name);
441                 }
442                 if (ino == null) {
443                     //debug("..cannot find - creating new"); // NOI18N
444
/*System.out.println("OutputView.Factory.getIO"
445                     + " CREATE NEW 2");*/

446                     ino = new OutputTabInner(name);
447                 }
448                 else {
449                     //debug("using existing"); // NOI18N
450
/*System.out.println("OutputView.Factory.getIO"
451                     + " USE EXISTING");*/

452                 }
453                 return ino;
454             }
455         }
456         
457         /** Returns standard output top component */
458         public TopComponent getStdOutputTab() {
459             //System.out.println("OutputView.Factory.getStdOutputTab");
460
//debug("OutputTabInner.Factory.getStdOutputTab()"); // NOI18N
461
initialize();
462             return standard;
463         }
464         
465     }
466
467     // OutputTabs are not serialized
468
// null is returned during deserialization
469
// only standard output tab is dseserialized to
470
// default instance
471

472     /** This class is serializaed instead of OutputView */
473     static class Replace implements java.io.Serializable JavaDoc {
474
475         private static final long serialVersionUID =-3237844916624172415L;
476
477         public Replace () {
478         }
479         
480         /** Resolve as default singleton or null */
481         public Object JavaDoc readResolve() throws java.io.ObjectStreamException JavaDoc {
482             return OutputView.getDefault();
483         }
484     }
485     
486 // public boolean isClosed() {
487
// //debug("isClosed()"); // NOI18N
488
// Workspace wrkSpace = WindowManager.getDefault().getCurrentWorkspace();
489
// return !isOpened(wrkSpace);
490
// }
491

492 // void ensureOpen() {
493
// //debug("ensureOpen()"); // NOI18N
494
// if (isClosed()) {
495
// //debug("opening"); // NOI18N
496
// open();
497
// }
498
// }
499

500     /** Returns true if given component is opened in OutputView */
501     public boolean isOpenedInOV (Component c) {
502         return openedComps.contains(c);
503     }
504     
505     /** Returns true if given component is closed and present in OutputView.
506      * For example it could be opened and closed. */

507     public boolean isClosedInOV (Component c) {
508         return closedComps.contains(c);
509     }
510     
511     /* Opens component in OutputView */
512     public void openInOV (final Component c) {
513         /* System.out.println("-- OutputView.openInOV ENTER"
514         + " c:" + c.getName()
515         + " [" + Integer.toHexString(System.identityHashCode(c)) + "]"
516         + " th:" + Thread.currentThread().getName()); */

517         //Open OutputView
518
Mutex.EVENT.readAccess(new Runnable JavaDoc() {
519             public void run() {
520                 /*System.out.println("-- OutputView.openInOV ENTER DELAYED"
521                 + " c:" + c.getName()
522                 + " [" + Integer.toHexString(System.identityHashCode(c)) + "]"
523                 + " th:" + Thread.currentThread().getName()); */

524                 //Open OutputView
525
if (!isOpened()) {
526                     open();
527                 }
528                 if (isOpenedInOV(c)) {
529                     //Already opened
530
/*System.out.println("-- OutputView.openInOV LEAVE 1 DELAYED"
531                     + " c:" + c.getName()); */

532                     return;
533                 }
534                 /* System.out.println("-- OutputView.openInOV DELAYED"
535                 + " c:" + c.getName()
536                 + " th:" + Thread.currentThread().getName()
537                 + " CALL OF addTab openedComps.size=" + openedComps.size()); */

538                 if (openedComps.size() == 0) {
539                     //Add component directly to OutputView
540
add(c);
541                     revalidate();
542                     setActivatedNodes(((TopComponent) c).getActivatedNodes());
543                     setName(baseName + " - " + c.getName());
544                     getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
545                         KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.CTRL_DOWN_MASK),
546                         "discard"); //NOI18N
547
getActionMap().put("discard", new DiscardAction());
548                 } else if (openedComps.size() == 1) {
549                     Component old = getComponents()[0];
550                     remove(old);
551                     JTabbedPane JavaDoc tab = getTabbedPane();
552                     add(tab);
553                     tab.addTab(old.getName(),old);
554                     tab.addTab(c.getName(),c);
555                     setActivatedNodes(((TopComponent) c).getActivatedNodes());
556                     setName(baseName);
557                     getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).remove(
558                         KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.CTRL_DOWN_MASK));
559                     getTabbedPane().addTab(c.getName(),c);
560                     setActivatedNodes(((TopComponent) c).getActivatedNodes());
561                 }
562                 if (closedComps.contains(c)) {
563                     closedComps.remove(c);
564                 }
565                 openedComps.add(c);
566                 if (openedComps.size() > 1) {
567                     JTabbedPane JavaDoc tab = getTabbedPane();
568                     if (tab.getTabCount() != openedComps.size()) {
569                         tab.add (c.getName(), c);
570                     }
571                 }
572                 /*System.out.println("-- OutputView.openInOV LEAVE 2 DELAYED"
573                 + " c:" + c.getName());*/

574             }
575         });
576         /*System.out.println("-- OutputView.openInOV LEAVE 2"
577         + " c:" + c.getName()
578         + " [" + Integer.toHexString(System.identityHashCode(c)) + "]");*/

579     }
580     
581     /** Creates and returns popup menu for given top component,
582      * filled with standard action presenters for window actions */

583     protected JPopupMenu JavaDoc createPopupMenu () {
584         JPopupMenu JavaDoc popup = new JPopupMenu JavaDoc();
585         JMenuItem JavaDoc menuItem = new JMenuItem JavaDoc
586         (NbBundle.getBundle(OutputView.class).getString("LBL_Discard"));
587         menuItem.setActionCommand("Discard");
588         menuItem.addActionListener(this);
589         popup.add(menuItem);
590         
591         menuItem = new JMenuItem JavaDoc
592         (NbBundle.getBundle(OutputView.class).getString("LBL_DiscardAll"));
593         menuItem.setActionCommand("DiscardAll");
594         menuItem.addActionListener(this);
595         popup.add(menuItem);
596         
597         return popup;
598     }
599
600     /** Shows given popup on given coordinations and takes care about the
601      * situation when menu can exceed screen limits */

602     protected void showPopupMenu (JPopupMenu JavaDoc popup, Point p, Component comp) {
603         SwingUtilities.convertPointToScreen (p, comp);
604         Dimension popupSize = popup.getPreferredSize ();
605         Rectangle screenBounds = Utilities.getUsableScreenBounds(getGraphicsConfiguration());
606         
607         if (p.x + popupSize.width > screenBounds.x + screenBounds.width) {
608             p.x = screenBounds.x + screenBounds.width - popupSize.width;
609         }
610         if (p.y + popupSize.height > screenBounds.y + screenBounds.height) {
611             p.y = screenBounds.y + screenBounds.height - popupSize.height;
612         }
613         
614         SwingUtilities.convertPointFromScreen (p, comp);
615         popup.show(comp, p.x, p.y);
616     }
617     
618     //
619
// Static stuff
620
//
621

622     static String JavaDoc getOutDisplayName() {
623         return NbBundle.getBundle(OutputView.class).getString("CTL_OutputWindow");
624     }
625     
626     //
627
// TopComponent methods
628
//
629

630     /** always open this top component in output mode, if
631     * no mode for this component is specified yet */

632     public void open (Workspace workspace) {
633         //debug("OutputTabInner.open():"+getName()); // NOI18N
634
if (!isShowing()) {
635             Workspace realWorkspace = (workspace == null)
636                 ? WindowManager.getDefault().getCurrentWorkspace()
637                 : workspace;
638             // dock into outwin mode if not docked yet
639
Mode mode = realWorkspace.findMode("output"); // NOI18N
640
if (mode == null) {
641                 mode = realWorkspace.createMode("output", getOutDisplayName(), // NOI18N
642
OutputView.class.getResource(ICON_RESOURCE));
643             }
644             Mode tcMode = realWorkspace.findMode(this);
645             if (tcMode == null) {
646                 mode.dockInto(this);
647             }
648             // behave like superclass
649
super.open(workspace);
650         } else {
651             requestActive();
652         }
653     }
654     
655     //
656
// inner classes
657
//
658

659     // Replacement for TopComponentListener. Listen on opened components.
660
public void propertyChange(PropertyChangeEvent JavaDoc evt) {
661     }
662
663     public void actionPerformed(ActionEvent e) {
664         if ("Discard".equals(e.getActionCommand())) {
665             discardTab();
666         } else if ("DiscardAll".equals(e.getActionCommand())) {
667             discardAllTabs();
668         }
669     }
670     
671     /* Close selected inner tab */
672     void discardTab () {
673         Mutex.EVENT.readAccess(new Runnable JavaDoc() {
674             public void run() {
675                 Component c = getSelectedComponent();
676                 if (c == null) {
677                     return;
678                 }
679                 discardTab(c);
680             }
681         });
682     }
683     
684     /** Called by OutputTabInner in doClose() to close the tab when the
685      * output is closed. Must be called on the event thread */

686     void discardTab (Component c) {
687         if (openedComps.size() > 2) {
688             getTabbedPane().remove(c);
689             setActivatedNodes(((TopComponent) getSelectedComponent()).getActivatedNodes());
690         } else if (openedComps.size() == 2) {
691             JTabbedPane JavaDoc tab = getTabbedPane();
692             remove(tab);
693             tab.remove(c);
694             Component old = tab.getComponentAt(0);
695             tab.remove(old);
696             add(old);
697             setActivatedNodes(((TopComponent) old).getActivatedNodes());
698             setName(baseName + " - " + old.getName());
699             getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
700                 KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.CTRL_DOWN_MASK),
701                 "discard"); //NOI18N
702
getActionMap().put("discard", new DiscardAction());
703         } else if (openedComps.size() == 1) {
704             getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).remove(
705                 KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.CTRL_DOWN_MASK));
706             remove(c);
707             setActivatedNodes(new Node[0]);
708             setName(baseName);
709         }
710         revalidate();
711         repaint();
712         openedComps.remove(c);
713         closedComps.add(c);
714     }
715     
716     /* Close all inner tabs */
717     void discardAllTabs () {
718         Mutex.EVENT.readAccess(new Runnable JavaDoc() {
719             public void run() {
720                 if (openedComps.size() > 1) {
721                     JTabbedPane JavaDoc tab = getTabbedPane();
722                     tab.removeAll();
723                     remove(tab);
724                 } else if (openedComps.size() == 1) {
725                     remove(((Component []) openedComps.toArray(new Component[1]))[0]);
726                     setName(baseName);
727                 }
728                 setActivatedNodes(new Node[0]);
729                 revalidate();
730                 repaint();
731                 closedComps.addAll(openedComps);
732                 openedComps.clear();
733             }
734         });
735     }
736     
737     /*private static void invokeLater(Runnable runnable) {
738     if (SwingUtilities.isEventDispatchThread()) {
739         runnable.run();
740     } else {
741             SwingUtilities.invokeLater(runnable);
742     }
743     }*/

744
745     /* DEBUG
746     private static void ckEventDispatchThread() {
747     if (!SwingUtilities.isEventDispatchThread()) {
748         System.out.println("OW: NOT IN EventDispatchThread");
749         Thread.dumpStack();
750     }
751     }
752     */

753 }
754
Popular Tags