FeaturesPluginsDocs & SupportCommunityPartners

NetBeans Anagram Game Module Tutorial

This tutorial demonstrates aspects of the NetBeans Windows API. It shows how to dock or embed the NetBeans Anagram Game in the IDE via a top component. A top component may correspond to a single window, but may also be, for example, a tab in a window. It may be docked or undocked, have selected nodes, supply actions, and provide other supporting functionality. For technical details on top components, see Class TopComponent in the NetBeans API List.

The following topics are covered below:

Once the software is installed, this tutorial can be completed in 45 minutes.

For more information on working with NetBeans plug-in modules, see the NetBeans Development Project home on the NetBeans website. If you have questions, visit the NetBeans Developer FAQ or use the feedback link at the top of this page.


Installing the Software

Before you begin, you need to install the following software on your computer:

Installing the Sample

Take the following steps to install the sample:

  1. Unzip the attached file.

  2. In the IDE, choose File > Open Project and browse to the folder that contains the unzipped file. Open the module project. It should look as follows:

    All source files.

  3. Right-click the project node and choose Install/Reload in Target Platform. The target platform opens and the module is installed.

    Notice that you have a new menu:

    Installed Menu.

  4. Choose the new menu. The Anagram Game opens and docks in the "explorer" mode, together with the Projects window, Files window, and Runtime window.

  5. Play the game.

Now that you know what the end result looks like, you will create the module from scratch and learn about each part while creating it.


Setting Up the Project

Creating the Module Project

  1. Choose File > New Project (Ctrl-Shift-N). Under Categories, select NetBeans Plug-in Modules. Under projects, select Module Project and click Next.
  2. In the Name and Location panel, type AnagramPlugin in Project Name. Change the Project Location to any directory on your computer, such as c:\mymodules. Leave the Standalone Module radiobutton and the Set as Main Project checkbox selected. Click Next.

  3. In the Basic Module Configuration panel, change the code name base to com.toy.anagrams. Leave the location of the localizing bundle and XML layer, so that they will be stored in a package with the name com/toy/anagrams. Click Finish.

    The IDE creates the AnagramPlugin project. The project contains all of your sources and project metadata, such as the project's Ant build script. The project opens in the IDE. You can view its logical structure in the Projects window (Ctrl-1) and its file structure in the Files window (Ctrl-2). For example, the Projects window should now look as follows:

    Initial Projects window.

    For basic information on each of the files above, see the Introduction to NetBeans Module Development.

Reimplementing the Anagram Game

Next, you need to get the NetBeans Anagram Game that is bundled with the IDE. Once you have it, you will replace one of its classes—instead of using JFrame, you need to use JComponent. Then, in the following sections, you will add a class that extends Class TopComponent and an action that extends Class CallableSystemAction.

  1. Choose File > New Project (Ctrl-Shift-N). Under Categories, select Samples and then select General. Under projects, select Anagram Game and click Next. Accept the defaults and click Finish.
  2. Expand the AnagramGame node and its Source Packages node. Use your mouse to drag the com.toy.angrams.lib package and the com.toy.angrams.ui package into the AnagramPlugin node's Source Packages node. The Projects window should now look as follows:

    Initial Projects window.

  3. Expand the com.toy.anagrams.ui package, right-click Anagrams.java and choose Delete. Click here to download a componentized version of Anagrams.java and place it in the com.toy.anagrams.ui package.

    The differences between the componentized and the original version of Anagrams.java are as follows:

    • The componentized Anagrams.java uses JComponent instead of JFrame.
    • No menu bar for the componentized Anagrams.java, because components are docked in modes, which don't support menu bars.
    • No exitMenuItemActionPerformed and no exitForm for the componentized Anagrams.java, because the Anagram Game will be a plug-in which will close together with the IDE.

    Note that you can use the IDE to diff the componentized Anagrams.java against the original. To do so, recreate the Anagram Game, select both Anagrams.java files, right-click, and then choose Tools > Diff in the contextual menu.


Docking the Anagram Game

Using the Window Component wizard

  1. Right-click the AnagramPlugin project node and choose New > Window Component. Click Next.

  2. In the Basic Settings panel, select explorer and select Open on Application Start.

    The Basic Settings panel should now look as follows:

    Window Component wizard, step 1.

    Click Next.

  3. In the Name and Location panel, type AnagramGame as the Class Name Prefix and and browse to any 16x16 pixel image file as the new file type's icon, as shown below.

    Window Component wizard, step 2.

    Note that several 16x16 pixel image files are found within your NetBeans installation directory, for example, in this location:

    enterprise2\jakarta-tomcat-5.5.7\server\webapps\admin\images.

    For purposes of this tutorial, the Datasource.gif image in the above directory is used. This is what it looks like: Datasource.gif

  4. Click Finish.

    The Projects window should now look as follows:

    Projects window with new window component.

    The IDE creates AnagramGameTopComponent.java in com.toy.anagrams and opens it in the Source Editor. This is what you should see (click on the links to see the related NetBeans API Javadoc):

    package com.toy.anagrams;
    
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.io.Serializable;
    import org.openide.util.NbBundle;
    import org.openide.util.RequestProcessor;
    import org.openide.util.Utilities;
    import org.openide.windows.TopComponent;
    
    /**
     * Top component which displays something.
     */
    final class AnagramGameTopComponent extends TopComponent {
    
        private static final long serialVersionUID = 1L;
    
        private static AnagramGameTopComponent instance;
    
        private AnagramGameTopComponent() {
            initComponents();
            setName(NbBundle.getMessage(AnagramGameTopComponent.class, "CTL_AnagramGameTopComponent"));
            setToolTipText(NbBundle.getMessage(AnagramGameTopComponent.class, "HINT_AnagramGameTopComponent"));
            setIcon(Utilities.loadImage("com/toy/anagrams/Datasource.gif", true));
        }
    
        /** 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.
         */
        //                           
        private void initComponents() {
    
            setLayout(new java.awt.BorderLayout());
    
        }
        //                         
    
    
        // Variables declaration - do not modify                     
        // End of variables declaration                   
    
        /**
         * Gets default instance. Don't use directly, it reserved for '.settings' file only,
         * i.e. deserialization routines, otherwise you can get non-deserialized instance.
         */
        public static synchronized AnagramGameTopComponent getDefault() {
            if (instance == null) {
                instance = new AnagramGameTopComponent();
            }
            return instance;
        }
    
        public int getPersistenceType() {
            return TopComponent.PERSISTENCE_ALWAYS;
        }
    
        public void componentOpened() {
            // TODO add custom code on component opening
        }
    
        public void componentClosed() {
            // TODO add custom code on component closing
        }
    
        /** replaces this in object stream */
        public Object writeReplace() {
            return new ResolvableHelper();
        }
    
        protected String preferredID() {
            return "AnagramGameTopComponent";
        }
    
        final static class ResolvableHelper implements Serializable {
            private static final long serialVersionUID = 1L;
            public Object readResolve() {
                return AnagramGameTopComponent.getDefault();
            }
        }
    
    }

    The IDE also creates AnagramGameAction.java. This is the action class for opening the window (click on the links to see the related NetBeans API Javadoc):

    package com.toy.anagrams;
    
    import java.awt.event.ActionEvent;
    import javax.swing.AbstractAction;
    import javax.swing.ImageIcon;
    import org.openide.ErrorManager;
    import org.openide.util.NbBundle;
    import org.openide.util.Utilities;
    import org.openide.windows.TopComponent;
    import org.openide.windows.WindowManager;
    
    /**
     * Action which shows AnagramGame component.
     */
    public class AnagramGameAction extends AbstractAction {
    
        public AnagramGameAction() {
            putValue(NAME, NbBundle.getMessage(AnagramGameAction.class, "CTL_AnagramGameAction"));
            putValue(SMALL_ICON, new ImageIcon(Utilities.loadImage("com/toy/anagrams/Datasource.gif", true)));
        }
    
        public void actionPerformed(ActionEvent evt) {
            TopComponent win = WindowManager.getDefault().findTopComponent("AnagramGameTopComponent");
            if (win == null) {
                ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find AnagramGame component.");
                return;
            }
            win.open();
            win.requestActive();
        }
    
    }

    The IDE registers the action class as a menu item and as a toolbar button in the layer.xml file:

    <filesystem>
       
        <folder name="Actions">
            <folder name="Window">
                <file name="com-toy-anagrams-AnagramGameAction.instance"/>
            </folder>
        </folder>
    
        <folder name="Menu">
            <folder name="Window">
                <file name="AnagramGameAction.shadow">
                    <attr name="originalFile" stringvalue="Actions/Window/com-toy-anagrams-AnagramGameAction.instance"/>
                </file>
            </folder>
        </folder>
    
        <folder name="Windows2">
            <folder name="Components">
                <file name="AnagramGameTopComponent.settings" url="AnagramGameTopComponent.xml"/>
            </folder>
            <folder name="Modes">
                <folder name="explorer">
                    <file name="AnagramGameTopComponent.wstcref" url="AnagramGameTopComponent_1.xml"/>
                </folder>
            </folder>
        </folder>
    
    </filesystem>

    When you open AnagramGameTopComponent.java and click Design, the Form Editor opens:

    Form editor.

    Normally, you would use the Form Editor to design your top component. However, in this case, you want to reuse the componentized version of the Anagram.java class that you downloaded at the start of this tutorial. The next step shows you how to do this.

  5. In the Source Editor, add the following method to AnagramGameTopComponent.java:

    protected void initAnagrams(){
        new Anagrams(this);
    }

    Then change the constructor so that the new method is called:

    private AnagramGameTopComponent() {
       initAnagrams();
       setName(NbBundle.getMessage(AnagramGameTopComponent.class, "CTL_AnagramGameTopComponent"));
       setToolTipText(NbBundle.getMessage(AnagramGameTopComponent.class, "HINT_AnagramGameTopComponent"));
       setIcon(Utilities.loadImage("com/toy/anagrams/Datasource.gif", true));
    }

    The line with the call to initAnagrams() is underlined and marked as an error, similar to the following illustration. This is because the related package has not been declared yet.

    Red underline.

    In the Source Editor, click Alt-Shift-F. An import statement for com.toy.anagrams.ui.Anagrams is added to the top of the class.

The plug-in module is now complete. Next, you need to install and use it.

Building and Installing the Module

The IDE uses an Ant build script to build and install your module. The build script is created for you when you create the module project.

Installing the NetBeans Module

  • In the Projects window, right-click the AnagramPlugin project and choose Install/Reload in Target Platform.

    The module is built and installed in the target platform. The target platform opens so that you can try out your new module. The default target platform is the installation used by the current instance of the development IDE. Note that when you run your module, you will be using a temporary test user directory, not the development IDE's user directory.

Using the Module

  1. In the IDE's menu bar, you should see the new menu and menu item, in the right place in the menu bar, together with myicon.gif:

    Installed Menu.

  2. Choose the menu item to invoke the performAction method in OpenAnagramAction.java. You should see the embedded Anagrams sample in the "explorer" mode:

    Result of choosing menu.

Creating a Shareable Binary

  1. In the Projects window, right-click the AnagramPlugin project and choose Create NBM.

    The NBM file is created and you can view it in the Files window (Ctrl-2):

    Shareable NBM.

  2. Make it available to others via, for example, e-mail.

Uninstalling the Module

  1. Close the platform instance that opened when you installed the module.
  2. Right-click the project node in the Projects window and choose Clean. Now you no longer have a module installed in the platform.

Next Steps

For more advanced tutorials, see the following resources:

For more information about creating and developing NetBeans plug-in modules, see the following resources:

Versioning

Version
Date
Changes
1 30 June 2005 Initial version
2 7 July 2005
  • Added source code and an introductory section that explains how to download and install the plug-in.
  • Added list of differences between original and componentized Anagrams.java files.
  • Added instruction about using the IDE to diff original and componentized Anagrams.java files.
  • Corrected the list of import statements required for the Action class.
  • Added localization in Bundle.properties for menu and menu item.
  • Sequencing of menus in menu bar shown.
  • Changed the last two screenshots, to show localization, sequencing, and explorer mode.
  • Added new sections: "Docking the NetBeans Plug-in Module in a Different Mode" and "Creating a Shareable Plug-in Binary"
  • Corrected one wrong reference to copy/paste error org.myorg.myfirstmodule.
3 11 July 2005
  • In "Implementing the Component" section, in the first step, added the name "AnagramPlugin" in the sentence to make it easier for the user to find the com.toy.anagrams package.
  • Two instances of "AnagramProject" changed to "AnagramPlugin".
  • Added "leftSlidingSide" and "rightSlidingSide" modes.
4 30 September 2005
  • Completely rewritten and radically simplified because of the Window Component wizard.

Issue Number Description Status
1 Code and tutorial itself need to be reviewed. To be fixed.
2 P1. Explanation to be added explaining what the difference is between the componentized anagrams.java and the original in the J2SE samples category in the New File wizard. To be fixed.
3 P1. Need to provide much more info on topcomponent. Modes, .wstcref, and .settings files not mentioned at all -- needs to be added. "Serializable" needs to be explained too. Also, need to add info about "What is a mode?", "What is a component?", (and maybe "What is a group?"). Links to FAQ. To be fixed.
4 P2. Add section on post-creation tasks:
  • Put in different mode.
  • Sequence action elsewhere in layer.xml
To be fixed.
5 P2. Use TODO window to find some comments and add some code. To be fixed.


Companion
Projects:
MySQL Database Server   Open JDK: an Open SourceJDK   GlassFish Community: an Open Source Application Server    Mobile & Embedded Community    Open Solaris   java.net - The Source for Java Technology Collaboration   Virtual Box - full virtualizer  Open ESB - The Open Enterprise Service Bus Powered by