Question

I'm creating an application using the Netbeans platform version 7.2 and JDK 1.7. I would like to be able to hide the tabs on my TopComponent elements that are installed to the editor position. I've googled around and found this post on Geertjan Wielenga's blog that appears to explain exactly what to do, but I still can't seem to make it work.

My application consists of two projects. One of them is a Netbeans module and the other is a "Netbeans Platform Application" project. The module consists of three classes: Installer.java, NoTabsTabDisplayerUI.java, and StupidTopComponent.java. Installer.java is pretty simple consisting of

package org.foo;

import javax.swing.UIManager;
import org.openide.modules.ModuleInstall;

public class Installer extends ModuleInstall {

    @Override
    public void restored() {
        UIManager.put("EditorTabDisplayerUI", "org.foo.NoTabsTabDisplayerUI");
    }
}

NoTabsTabDisplayerUI.java is taken more or less verbatim from Geertjan's blog and looks like

package org.foo;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import javax.swing.DefaultSingleSelectionModel;
import javax.swing.JComponent;
import javax.swing.SingleSelectionModel;
import javax.swing.plaf.ComponentUI;
import org.netbeans.swing.tabcontrol.TabDisplayer;
import org.netbeans.swing.tabcontrol.TabDisplayerUI;

public class NoTabsTabDisplayerUI extends TabDisplayerUI {

    public NoTabsTabDisplayerUI(TabDisplayer displayer) {
        super(displayer);
    }

    public static ComponentUI createUI(JComponent jc) {
        assert jc instanceof TabDisplayer;
        return new NoTabsTabDisplayerUI((TabDisplayer) jc);
    }

    private static final int[] PTS = new int[] { 0, 0, 0 };
    @Override
    public Polygon getExactTabIndication(int i) {
        //Should never be called
        return new Polygon(PTS, PTS, PTS.length);
    }

    @Override
    public Polygon getInsertTabIndication(int i) {
        return new Polygon(PTS, PTS, PTS.length);
    }

    @Override
    public int tabForCoordinate(Point point) {
        return -1;
    }

    @Override
    public Rectangle getTabRect(int i, Rectangle rectangle) {
        return new Rectangle(0,0,0,0);
    }

    @Override
    protected SingleSelectionModel createSelectionModel() {
        return new DefaultSingleSelectionModel();
    }

    public java.lang.String getCommandAtPoint(Point point) {
        return null;
    }

    @Override
    public int dropIndexOfPoint(Point point) {
        return -1;
    }

    @Override
    public void registerShortcuts(javax.swing.JComponent jComponent) {
        //do nothing
    }

    @Override
    public void unregisterShortcuts(javax.swing.JComponent jComponent) {
        //do nothing
    }

    @Override
    protected void requestAttention(int i) {
        //do nothing
    }

    @Override
    protected void cancelRequestAttention(int i) {
        //do nothing
    }

    @Override
    public Dimension getPreferredSize(javax.swing.JComponent c) {
        return new Dimension(0, 0);
    }

    @Override
    public Dimension getMinimumSize(javax.swing.JComponent c) {
        return new Dimension(0, 0);
    }

    @Override
    public Dimension getMaximumSize(javax.swing.JComponent c) {
        return new Dimension(0, 0);
    }
}

StupidTopComponent.java is just a TopComponent with a label on it. The code goes like this:

package org.foo;

import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.windows.TopComponent;
import org.openide.util.NbBundle.Messages;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(
    dtd = "-//org.foo//Stupid//EN",
autostore = false)
@TopComponent.Description(
    preferredID = "StupidTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE", 
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "editor", openAtStartup = true)
@ActionID(category = "Window", id = "org.foo.StupidTopComponent")
@ActionReference(path = "Menu/Window" /*, position = 333 */)
@TopComponent.OpenActionRegistration(
    displayName = "#CTL_StupidAction",
preferredID = "StupidTopComponent")
@Messages({
    "CTL_StupidAction=Stupid",
    "CTL_StupidTopComponent=Stupid Window",
    "HINT_StupidTopComponent=This is a Stupid window"
})
public final class StupidTopComponent extends TopComponent {

    public StupidTopComponent() {
        initComponents();
        setName(Bundle.CTL_StupidTopComponent());
        setToolTipText(Bundle.HINT_StupidTopComponent());

    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();

        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(StupidTopComponent.class, "StupidTopComponent.jLabel1.text")); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(74, 74, 74)
                .addComponent(jLabel1)
                .addContainerGap(267, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(88, 88, 88)
                .addComponent(jLabel1)
                .addContainerGap(198, Short.MAX_VALUE))
        );
    }// </editor-fold>

    // Variables declaration - do not modify
    private javax.swing.JLabel jLabel1;
    // End of variables declaration
    @Override
    public void componentOpened() {
        // TODO add custom code on component opening
    }

    @Override
    public void componentClosed() {
        // TODO add custom code on component closing
    }

    void writeProperties(java.util.Properties p) {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty("version", "1.0");
        // TODO store your settings
    }

    void readProperties(java.util.Properties p) {
        String version = p.getProperty("version");
        // TODO read your settings according to their version
    }
}

The platform application project then just includes this module. When I run it, it still shows the tab on the TopComponent.

Running it in the debugger, I never see it hit any of the code in NoTabsTabDisplayerUI.java. It never seems to call the constructor or any of the other functions in that class. My first thought was that it wasn't finding the class for some reason, but I'm not sure how to test whether that's the case or not.

Is there something obvious that I'm missing here?

Was it helpful?

Solution

You'll need to wrap the call to UIManager.put() in a Runnable and run it on the EDT:

SwingUtilities.invokeLater(new Runnable() {

    @Override
    public void run() {
        UIManager.put("EditorTabDisplayerUI", "org.foo.NoTabsTabDisplayerUI");
    }
});

You didn't need to do it like this in the version of NB that Geertjan was using for that blog post.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top