Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Many Apps will include image files and other content. To include these, create a directory named "resources" at the same level as the pom.xml file, as seen in the image above.

pom.xml

...

Code Block
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.affymetrix</groupId>
        <artifactId>igb-project</artifactId>
        <version>9.0.0</version>
    </parent>
    <groupId>org.lorainelab.igb</groupId>
    <artifactId>org.lorainelab.igb.menu.api.example</artifactId>
    <version>1.0.0</version>
    <packaging>bundle</packaging>

    <name>IGB Menubar Extension</name>
    
    <dependencies>
        <dependency>
            <groupId>biz.aQute.bnd</groupId>
            <artifactId>bndlib</artifactId>
            <scope>provided</scope>
        </dependency>
          <dependency>
            <groupId>org.lorainelab.igb</groupId>
            <artifactId>org.lorainelab.igb.menu.api</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <id>build plugin repository</id>
                        <goals>
                            <goal>
                                index
                            </goal>                       
                        </goals>
                        <phase>package</phase>
                        <configuration>
                            <obrRepository>${project.build.directory}</obrRepository>    
                            <mavenRepository>${project.build.directory}</mavenRepository>                      
                        </configuration>
                    </execution>
                </executions>
                <configuration>
                    <instructions>
                       <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
                        <Import-Package>*</Import-Package>
                        <Export-Package/>
                        <Service-Component>*</Service-Component>
                    </instructions>
                </configuration>
            </plugin>     
        </plugins>
    </build>
</project>

...

 

Code Block
languagejava
titleIgbMenuItemProvider
public interface IgbMenuItemProvider {
    public IgbToolBarParentMenu getParentMenu();
    public JRPMenuItem getMenuItem();
    public int getMenuItemWeight();
}

 

Note that this interface will likely change in future releases of the IGB API. The getParentMenuName method will likely a custom enum type and not a String literal.  Additionally, we will add "weight" as an attribute to our custom JMenuItem class.  So it is likely this interface will ultimately contain one simple getMenuItem() method.  

Create  new Java class IgbToolbarExtension 

Within NetBeans, check that your "hello world" project is the currently selected project - the name of the currently opened project is shown on the NetBeans title bar. If it isn't, select File > Open Project to open it.

Next, create a new Java class named IgbToobarExtension:

  • Select File > New File
  • Under Choose File Type, select Java
  • Select Next
  • Enter class Name IgbToolbarExtension
  • Select package com.lorainelab.plugin
  • Select Finish

Edit your file to match the following code into your new Java class file.

Note that NetBeans has added the package and class declarations.

 

Code Block
languagejava
package com.lorainelab.plugin;

import aQute.bnd.annotation.component.Component;
import com.affymetrix.igb.swing.JRPMenuItem;
import com.lorainelab.igb.services.window.menus.IgbMenuItemProvider;
import com.lorainelab.igb.services.window.menus.IgbToolBarParentMenu;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import static javax.swing.Action.MNEMONIC_KEY;
import static javax.swing.Action.SHORT_DESCRIPTION;
import javax.swing.ImageIcon;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

// annotations processed by BND tool
@Component(name = IgbToolbarExtension.COMPONENT_NAME, immediate = true, provide = IgbMenuItemProvider.class)
public class IgbToolbarExtension implements IgbMenuItemProvider {
    public static final String COMPONENT_NAME = "IgbToolbarExtension";
    private static final Logger logger = LoggerFactory.getLogger(IgbToolbarExtension.class);
    private static final int MENU_ITEM_INDEX = 4;
    private final JRPMenuItem exampleMenuItem;
    public IgbToolbarExtension() {
        exampleMenuItem = new JRPMenuItem("exampleIgbToolbarMenuItem", new LogEventAction(), MENU_ITEM_INDEX);
    }

    @Override
    public JRPMenuItem getMenuItem() {
        return exampleMenuItem;
    }
 
    @Override
    public IgbToolBarParentMenu getParentMenu() {
        return IgbToolBarParentMenu.TOOLS;
    }
    @Override
    public int getMenuItemWeight() {
        return MENU_ITEM_INDEX;
    }
    private class LogEventAction extends AbstractAction {
        public LogEventAction() {
            this("Hello IGB Toolbar", null, "", null);
        }
        public LogEventAction(String text, ImageIcon icon,
                String desc, Integer mnemonic) {
            super(text, icon);
            putValue(SHORT_DESCRIPTION, desc);
            putValue(MNEMONIC_KEY, mnemonic);
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            logger.info("Hello Igb Toolbar menu item clicked");
        }
    }
}

 

About the implementation class

The @Component annotation 

Code Block
languagejava
@Component(name = IgbToolbarExtension.COMPONENT_NAME, immediate = true, provide = IgbMenuItemProvider.class)
public class IgbToolbarExtension implements IgbMenuItemProvider {...}

This annotation is processed by the felix maven-bundle-plugin (BND) and declares that the OSGi runtime will manage creation and destruction of any instances of this class. This is an important point to understand about how OSGi-based applicaitions function. Your code will not directly manage the life cycle of your class. Instead, you specify the behavior and lifecycle of your objects using annotations.

The immediate=true annotation attribute specifies to the OSGi runtime that this component should be instantiated immediately instead of lazily. 

See http://www.aqute.biz/Bnd/Components for more information about the annotation attributes.

The LogEventAction

When a user selects your new menu item, this action will execute. Note it prints a message to the IGB console. Note also that it uses the SLF4j API to log events to the IGB console

Build the App

To build your App, select Run > Build in NetBeans.

Alternatively, you can build it from the command line by entering:

Code Block
languagebash
mvn clean install

 

Install the App in IGB

Start IGB and add your target directory as a new plugin repository (local App store)

  1. Re-open IGB project (double-click it in the Projects tab or use File > Open Project)
  2. Open the IGB "main" sub-project; select IGB Project > Modules > main
  3. Select Run to run IGB
  4. Within IGB, select the Plug-Ins Tab
  5. Select Launch App Manager to open the App Manager window
  6. Within the App manager, select Manage Repositories... (top right corner). This opens the App Repositories tab in the IGB Preferences window
    1. Image Removed
  7. Within the App Repositories tab in the Preferences window, select Add 
  8. Enter a name for your repository, and then select the Choose local folder button
    1. Image Removed
  9. Select the target directory of your maven project and click submit. The target directory is the actual target directory created by maven when you built your App.
    1. Image Removed
  10. Close the Preferences window and return to the IGB App Manager
  11. Note that your App should now appear in the left pane of the IGB App Manager. Select it and click the Install button. This will cause the OSGi run-time to instantiate your new menu item and add it to IGB.
    1. Image Removed

Run your new App

To run your app:

  • Open the IGB console by selecting Help > Show Console
  • Open the Tools menu in IGB. Observe your Hello IGB Toolbar menu item is an option.
  • Select Tools > Hello IGB Toolbar to run your App; observe the message printed to the console:

Image Removed

Note that your new menu item is an option under the Tools menu in IGB. If you return to the App Manager and uninstall your App, this menu item will disappear from IGB.

Image Removed

 

Next step: Modify your code

Re-open your IGB App project. Edit the message your IGB App prints and re-build your App. Then, return to the IGB App Manager, un-install and then re-install your App. When you select the the menu item again, the new message will print instead of the old one.

Note that you can rapidly repeat this edit-build-uninstall-install cycle. You don't have to re-build IGB or even restart it, which makes development much faster than if you had to modify the IGB code directly.

Next step: Make README.md for your App

It's not enough to create and deploy an App; you should also provide an easy-to-understand README.md file suitable for display in the IGB App Manager. See Create Markdown to display in IGB App Manager

Completed Project Reference

git clone https://bitbucket.org/lorainelab/igb-app-hello-world.git