// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= DevFaqOWTabEmbedding
:jbake-type: wiki
:jbake-tags: wiki, devfaq, needsreview
:jbake-status: published
:keywords: Apache NetBeans wiki DevFaqOWTabEmbedding
:description: Apache NetBeans wiki DevFaqOWTabEmbedding
:toc: left
:toc-title:
:syntax: true

== How do I embed output window tab to another component?

You have to create `IOContainer` which provides access (for `IOProvider`) to your component where you want to embed OW tab (IO tab). Then you need to pass `IOContainer` instance to `IOProvider.getIO(String name, Actionlink:_.asciidoc[ ] actions, IOContainer ioContainer)`. `IOContainer` is created by `IOContainer.create(IOContainer.Provider)`. The following code demonstrates how to add OW to custom TopComponent.:

[source,java]
----

    IOContainer ioc = IOContainer.create(new IOC());
    InputOutput io = IOProvider.getDefault().getIO("test", new Action[0], ioc);
    io.getOut().println("Hi there");
    io.select();

    // implement IOContainer.Provider in TopComponent where OW tab will be added
    class IOC extends TopComponent implements IOContainer.Provider {
        JComponent ioComp;
        CallBacks ioCb;

        public IOC() {
            setLayout(new BorderLayout());
            setDisplayName("Test");
        }

        @Override
        public int getPersistenceType() {
            return PERSISTENCE_NEVER;
        }

        public void add(JComponent comp, CallBacks cb) {
            if (ioComp != null) {
                remove(ioComp);
                if (ioCb != null) {
                    ioCb.closed();
                }
            }
            ioComp = comp;
            ioCb = cb;
            add(comp);
            validate();
        }

        public JComponent getSelected() {
            return ioComp;
        }

        boolean activated;
        public boolean isActivated() {
            return activated;
        }

        @Override
        protected void componentActivated() {
            super.componentActivated();
            activated = true;
            if (ioCb != null) {
                ioCb.activated();
            }
        }

        @Override
        protected void componentDeactivated() {
            super.componentDeactivated();
            activated = false;
            if (ioCb != null) {
                ioCb.deactivated();
            }
        }

        public boolean isCloseable(JComponent comp) {
            return false;
        }

        public void remove(JComponent comp) {
            if (comp == ioComp) {
                ioComp = null;
                ioCb = null;
            }
        }

        public void select(JComponent comp) {
        }

        public void setIcon(JComponent comp, Icon icon) {
        }

        public void setTitle(JComponent comp, String name) {
        }

        public void setToolTipText(JComponent comp, String text) {
        }

        public void setToolbarActions(JComponent comp, Action[] toolbarActions) {
        }
    }
----

<hr/>
Applies to: NetBeans 6.7

=== Apache Migration Information

The content in this page was kindly donated by Oracle Corp. to the
Apache Software Foundation.

This page was exported from link:http://wiki.netbeans.org/DevFaqOWTabEmbedding[http://wiki.netbeans.org/DevFaqOWTabEmbedding] , 
that was last modified by NetBeans user Admin 
on 2009-11-06T15:58:04Z.


*NOTE:* This document was automatically converted to the AsciiDoc format on 2018-02-07, and needs to be reviewed.
