This tutorial shows how to create a renderer for Instant JChem. A renderer controls the formatting of a field type used to display data. For example, a renderer can set the alignment and font of integers, which can be different to the alignment and font of floats. Each renderer is capable of rendering only some type of data and therefore can be use for rendering only certain field types. For each field it is possible to choose a renderer from the list of renderers available for this field type.
This tutorial assumes that you have worked through IJC Plugin: Quick Start and IJC Plugin: Hello World! tutorials and that you are familiar with the concepts and instructions described therein. As before, you will use NetBeans IDE to create the example plugin that will extend Instant JChem.
Contents:
- Exploring 'Renderers' plugin example
- Using the IDE's Wizards
- Coding the Module
- Building and running the plugin
- Conclusion
Before we begin, let's look at the sample that we will build in this tutorial.
api-examples-suite
project as described in
IJC Plugin: Quick Start
'File' -> 'New Project...'
and choosing
'General' -> 'IJC Project (local database with demo data)'
in the 'New Project' wizard.
'localdb' -> 'Pubchem demo' -> 'Pubchem grid view'
view.
Instant JChem with the demo project - customizing the table widget
'Cell Renderer'
drop-down list, which is
the first item under 'Column properties'
.
You should now see the following:
Instant JChem with the demo project - cell renderers available for 'LogP' column
'Simple Colouring Renderer'
. This is the renderer
that we will create in this tutorial.
'Simple Colouring Renderer'
and you will see its
properties.
Instant JChem with the demo project - Simple Colouring Renderer's settings
Instant JChem with the demo project - Simple Colouring Renderer in action
Now that you are familiar with the feature that we are going to create in this tutorial we can dive straight in.
If you followed the IJC Plugin: Hello World! 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 'MyColourRendererPlugin'
and don't forget to add it to 'IJC-Extensions' module suite.
As the module's 'Code Name Base' enter org.myorg.mycolourrendererplugin
and tick the 'Generate XML Layer' checkbox, leave the default location offered for
the 'XML Layer' file.
New 'MyColourRendererPlugin' module project in NetBeans IDE's 'Projects' explorer
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'.
'Libraries' -> 'Module Dependencies'
and click 'Add Dependency...'
button to specify modules
that 'MyColourRendererPlugin' module will use.
Commons - UI and Graphics
,
DIF API
, DIF Core Implementation
,
Instant JChem Core
, Library - JChem
,
Lookup
, UIWidget Renderers
, Utilities API
.
'OK'
and close the 'Properties' dialog.
The list of module dependencies in the 'Project Properties' dialog should look like this.
'MyColourRendererPlugin' module dependencies
The dependencies we have just added as well as reasons for adding them (i.e. the classes these modules provide in their API) are summarized in the following table.
Module | Description | Classes that we need |
---|---|---|
DIF API DIF Core Implementation (Discovery Informatics Framework) |
Provides the data model and persistence tiers for applications that need to use chemical and biological data. |
|
Instant JChem Core | Provides the basic user interface for Instant JChem and through its API it provides the ability to extend the IJC user interface. |
|
Library - JChem | Provides the data model and persistence tiers for applications that need to use chemical and biological data. |
|
Utilities API | Provides a set of utility classes covering general infrastructure points in the NetBeans Platform. |
|
First, let's begin by creating an implementation of
RendererFactory.
This interface creates a renderer, depending on the level of suitability of the renderer
for the field. Suitability is determined by the
RendererFactory.getSuitabilityFor()
method. The suitability level is an int
between 0 (not supported) and 100 (best renderer for
the given field). Below, if the field is an integer or a float, the suitability of the
renderer is set to 30. As a result, it will most likely not be the default renderer, because
other renderers are likely to have higher suitability levels.
Of the three types of widgets available, we will make our renderer applicable to table cells and IJC widget texts.
org.myorg.mycolourrendererplugin
,
create a Java class called ColouringRendererFactory
.
ColouringRendererFactory.java source file
Add the following to the layer.xml
file. These entries create a new folder
called IJC
, with a subfolder called RendererFactories
.
Within that folder, we register our implementation of the RendererFactory
interface.
layer.xml source file
Let's create the renderer.
ColouringRenderer
in the main package org.myorg.mycolourrendererplugin
.
ColouringRenderer.java source file
ColouringRendererFactory
class that you created
earlier and change the body of createTableCellRenderer()
and createWidgetTextRenderer()
methods. Return a new
instance of ColouringRenderer
class as shown below.
Code snippet - ColouringRendererFactory
class, createTableCellRenderer()
and createWidgetTextRenderer()
methods.
Let's create the bean info class.
ColouringRendererBeanInfo
.
ColouringRendererBeanInfo.java source file
Bundle.properties
file:
Bundle.properties source file
Add the following code to the IJC
folder in the layer.xml
:
Code snippet - layer.xml
file
The new persistence folder that you need to add, as shown above,
contains registration entries for writer-factories and reader-factories
that store or read UI object settings. When a JavaBean is to be written,
Instant JChem looks up a writer (persister), using the class name (obj.getClass().getName()
)
to write the state to XML format. If such a persister is not registered, the
persister for the superclass is tried, etc. A Beaninfo-based Persister is
registered for java.lang.Object
, so each Object
is ultimately written, but the object's class name is stored in the XML file,
and all such objects create the element <ijc:simpleBean>
in the XML.
Therefore, if possible, you should register the persister for a class,
in order to get a nice XML element with a tag composed of "namespace":"localName"
,
which looks better. But, mainly, the reason you need to do
this is to give Java Class names (which are implementation details that may
change from release to release) "abstract" XML element names. You are free
to change the implementation classes, provided that a Persister
is registered to the element xmlns:localName
in a future Instant JChem releases
and assuming you will still be able to read old data.
There is boilerplate support for persisting (reading/writing) Beans
implemented in the FSPersisterFactory
class, which gets the BeanInfo
for the persisted object and stores properties described by the BeanInfo,
using BeanInfo-published get
and set
methods. Primitive values are stored
as attributes, Object values are saved (read) using Persister for the type
declared in the BeanInfo (or the actual type). Therefore, for simple objects,
the simple declaration shown above is fine. For this basic support, these
attributes are necessary:
localName/namespace
- name of the XML elementimplClass
- the class which should be created when the object is read
For writing Beans, the Persister must be registered as follows:
/persistence/classes/class-name-with-dots-replaced-by-underscores
.
For reading Beans, the Persister must be registered as follows:
/persistence/xmlns/namespace-with-nonalphanum-replaced-by-underscores/localname-with-replaced-nonalphanum
.
You are recommended to register these using .instance
DataObjects (using the .instance
extension and instanceCreate
and class
attributes), since this is what is directly supported by the NetBeans platform.
This Colouring Renderer example has a BeanInfo class that
declares three properties. One of them is a 'float' type (a primitive). There is
also a common Persister for the java.awt.Color
class available,
which encodes the Color
object as an attribute that contains a hexadecimal color value.
In other words, the FSPersisterFactory
, as declared above, will follow
the BeanInfo, serialize (or read) the splitValue
as an attribute,
and the lowerColor
and higherColor
using
the Color
persister. In effect, the ColouringRenderer
is serialized as something like this (xml namespaces and implementation detail
attributes are omitted for clarity):
<renderer splitValue="1.0" higherColor="#ffffff" lowerColor="#00000"/>
If you've followed this tutorial closely you should now have all files in your 'MyColourRendererPlugin' project ready. The project in NetBeans IDE's 'Projects' explorer should look like the picture below.
Complete 'MyColourRendererPlugin' project in NetBeans IDE's 'Projects' explorer
You can now r-click the project's node and build the project by choosing 'Clean and Build' and then run it by invoking 'Run' from the same popup menu. Instant JChem will start with MyColourRendererPlugin installed and the renderer that we have created will be available in the table widget settings customizer.
Congratulations, you have created your first renderer for InstantJchem. In this tutorial you have learned:
layer.xml
.For other IJC plugin development related tutorials please see their complete list here.