This tutorial will introduce you to the basics of IJC plugin development and using Instant JChem APIs. It will walk you step by step through the process of creating 'Add Field' IJC plugin included in IJC API Examples suite.
In this tutorial we expect that you have made yourself familiar with the development tools and set up your environment as it is described in IJC Plugin Quick Start and IJC Hello World Plugin tutorials. If you haven't done so, we strongly recommend you to read these two tutorials first before you proceed with the 'Add Field' plugin tutorial.
During this tutorial we are going to create our own version of the 'Add Field' plugin, which is available as part of IJC API Examples suite. This gives you chance to choose how exactly you want to follow this tutorial. You can either recreate the plugin step by step as described here or you can use this tutorial as a guide for exploring the 'Instant JChem API Examples - Add Field' project that you have downloaded as part of api-examples-suite
in IJC Plugin Quick Start tutorial.
By the end of this tutorial, you will understand the basic process of creating new extensions for IJC and you will also have been introduced to various resources that you can use to further develop your knowledge and skill in extending IJC. In particular, in this tutorial you will learn the following:
How to add a context-aware menu item and toolbar button
How to create and open new dialogs
How to create new fields in a JChem table
How to read data from a JChem table
How to write data to a JChem table
How to use asynchronous tasks running in the background
Before we begin creating our module, let's look at the sample that we will build in this tutorial. Once we have tried it out, we will know for ourselves what the result of this tutorial will be.
1.
Start api-examples-suite
project as described in IJC Plugin Quick Start
1.
In the started Instant JChem create a new IJC project by going to the main menu File -> New Project...
and choosing General -> IJC Project (local database with demo data)
in the 'New Project' wizard.
1.
In the 'Projects' explorer open localdb -> Pubchem demo -> Pubchem tabular form
view.
1.
Now, add the atom count field by selecting the Add Atom count field
menu item in the main menu Help -> API Examples
.
1.
You should now see the new Atom Count
field added to the JChem table.
Note: In this tutorial, you will learn, among many other things, how to create a progress bar to enable asynchronous tasks to run in the background, so that the user interface remains enabled while the field is being added to the table. In this tutorial we are going to implement the same functionality from scratch.
If you followed the IJC Hello World Plugin tutorial you should have 'IJC Extensions' module suite and 'HelloWorldPlugin' module already available. Open 'IJC Extensions' suite project in NetBeans IDE, we will add a new module to it.
In your IDE go to main menu File -> New Project...
and create a new NetBeans Modules -> Module
project. Call the project MyAddFieldPlugin
and don't forget to add it to IJC-Extensions
module suite. As the module's 'Code Name Base' enter org.myplugin.myaddfieldplugin
.
Our next step is to specify which APIs we want to use. Each API is provided by a module. Some of the APIs belong to the NetBeans API, while others belong to the Instant JChem API. Because our module is deployed to Instant JChem (ie. 'IJC Platform' that we set up earlier), which itself makes use of all NetBeans and Instant JChem APIs that we need, we can simply just set dependencies on modules available in 'IJC Platform'.
1.
In 'Projects' explorer r-click the MyAddFieldPlugin
project's node and in the popup menu choose Properties
. The 'Project Properties' dialog will appear.
1.
In the 'Project Properties' dialog go to Libraries -> Module Dependencies
and click Add Dependency...
button to specify modules that 'MyAddFieldPlugin' module will use.
1. In the 'Add Module Dependency' dialog choose the modules shown here:
<img src="images/download/attachments/1802771/add-dependencies.png" alt="images/download/attachments/1802771/add-dependencies.png"/>
1.
Click OK
button and close the 'Properties' dialog by OK
button as well.
In this section, we use the 'New Action' wizard to create a menu item and toolbar button that will be context-aware, which means that they will only be enabled when needed. In this tutorial's scenario, the menu item and toolbar button will only be enabled when a table, also known as an 'entity', is selected in IJC. Once we have completed the wizard, we will have a skeleton "action", which the user will be able to invoke either from the menu item or from the toolbar button, if enabled. Later on we will fill out this action with additional functionality needed for this module.
1.
Right-click the module project node in the 'Projects' explorer and choose New -> Action
.
1.
In the first panel, specify that you want to create a Conditionally Enabled
action that will be sensitive to 'EntityCookie', which represent tables in IJC. Type com.im.ijc.core.api.cookie.EntityCookie
into 'Cookie Class' field as shown here:
<img src="images/download/attachments/1802771/add-action1.png"/>
Click `Next` button.
1.
In the next panel, specify that the action will appear in the Edit
menu and in the Edit
toolbar, as shown below:
<img src="images/download/attachments/1802771/add-action2.png"/>
Click `Next` button.
1.
In the final panel, type AddAtomCountFieldAction
in 'Class Name' field. Type Add Atom Count Field
in 'Display Name' field.
Click `Browse...` button for action's icon. Browse to a 16x16 pixel icon, which will be displayed in the toolbar button. If there is a 24x24 pixel icon with the same name scheme, the IDE will recognize it. For example, if the first icon is named 'icon-16.png', the IDE will assume the second icon is named 'icon-24.png'. Ideally, you will have a small icon (16x16 pixels) and a large icon (24x24 pixels) available. If not, here are two icons that you can use for this purpose these icons: <img src="images/download/attachments/1802771/icon-16.png"/> <img src="images/download/attachments/1802771/icon-24.png"/>
You should now see the following configuration:
<img src="images/download/attachments/1802771/add-action3.png"/>
1.
Click Finish
button.
The wizard creates a new 'AddAtomCountFieldAction' class. In addition, the icons are copied into the module. You should see the action class in NetBeans 'Projects' explorer:
As you can see the action class and its parent nodes are marked with the red error badge. This indicates that something is broken in the class. Let's open the class and examine it. You will notice that the line referring to EntityCookie
is underlined in red, which means that the java compiler does not know EntityCookie
class. In this case, we need to add an import statement for the EntityCookie
. Right-click in the editor and choose Fix Imports
(Ctrl-Shift-I
). The IDE adds the import statement and the red underline disappears:
Before launching the generated action, let's examine the artifacts that the 'New Action' wizard generated for us. The generated action class looks as follows:
package org.myplugin.myaddfieldplugin;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionReferences;
import org.openide.awt.ActionRegistration;
import org.openide.util.NbBundle.Messages;
import com.im.ijc.core.api.cookie.EntityCookie;
@ActionID(
category = "Edit",
id = "org.myplugin.myaddfieldplugin.AddAtomCountFieldAction"
)
@ActionRegistration(
iconBase = "org/myplugin/myaddfieldplugin/icon-16.png",
displayName = "/display/lts-mercury/instant-jchem_ijc-plugin-tutorial-myaddfield-plugin.md#CTL_AddAtomCountFieldAction"
)
@ActionReferences({
@ActionReference(path = "Menu/Edit", position = 1500, separatorBefore = 1450),
@ActionReference(path = "Toolbars/Edit", position = 600)
})
@Messages("CTL_AddAtomCountFieldAction=Add Atom Count Field")
public final class AddAtomCountFieldAction implements ActionListener {
private final EntityCookie context;
public AddAtomCountFieldAction(EntityCookie context) {
this.context = context;
}
@Override
public void actionPerformed(ActionEvent ev) {
// TODO use context
}
}
Let's put a dummy message inside actionPerformed
method to see if it works. Edit the method like this:
@Override
public void actionPerformed(ActionEvent ev) {
javax.swing.JOptionPane.showMessageDialog(null, "This is AddAtomCountFieldAction!");
}
Save the changes (Ctrl + S
).
We can now try out the module and see if the action works. The action's menu item and toolbar button should be enabled and disabled depending on what is selected in Instant JChem.
1.
Right-click the MyAddFieldPlugin
project's node and choose Run
. The IDE will deploy the plugin and start Instant JChem. You should see the action's toolbar button and also the Add Atom Count Field
menu item in the main menu Edit
.
1. Open an IJC project or create a new one if you don't have any (use localdb with demo data).
1.
In the IJC project open Pubchem demo -> Pubchem grid view
and both the toolbar button and the menu item for our action should become enabled.
<img src="images/download/attachments/1802771/enabled.png"/>
1. If you click the action, message box appears:
<img src="images/download/attachments/1802771/message.png"/>
1.
If you click back to Instant JChems 'Projects' explorer and select its 'Pubchem demo' -> 'Pubchem grid view'
node the button and the menu item will become disabled. This is because the selected node does not provide the EntityCookie
while the opened 'Pubchem grid view' editor provides this cookie.
Currently performAction()
method displays simple message. Let's open com.im.ijc.examples.addfield.AddAtomCountFieldAction
from api-examples-suite
. Examine the code and compare it with ours AddAtomCountFieldAction
generated above. Start in performAction()
method. The code creates new field (by using asynchronous tasks running in background). The 'field' means in IJC's case is a database column in the specified entity, which is a database table. Then it invokes a method that fills all the rows with data. If you code the action the same way as the action in API Examples is, then run it upon opened 'Pubchem grid view', you should see new column in the gridview called 'Atom count' and fill with values.
1. Run the module again, as described in Running the Module.
1. Make sure 'Pubchem grid view' is open in the editor area.
1.
Click the new toolbar button or invoke Edit -> Add Atom Count Field
menu item. It will add a new field called "Atom Count" to 'Pubchem demo' entity and will fill it with the actual atoms count for each structure.
Note: In the bottom right corner of the screenshot above there is a progress bar there that lets asynchronous tasks running in background give feedback to users. The user interface remains enabled while the field is being added and filled with data.
Congratulations! You have successfully completed an IJC plugin that adds a new field to an existing entity and fills it with the atom count for each structure in the entity. In this tutorial you have learned:
How to create a conditionally enabled action and install it in Instant JChem's UI.
How to find an existing structure field in an IJC entity.
How to add a new field to an existing entity
How to read data from and write data to fields in an entity.
How to create a background task and use the progress bar to give a user feedback about the task's progress.
For other IJC plugin development related tutorials please see their complete list here.