Swing Visual Plugins

This article describes how to create a new visual Java plugin, what features it provides and how they can be used.

Getting Started

A Java-based Hydra plugin project consists of a three parts:

  • Plugin Descriptor - a special class that provides plugin information like its name, version and, the most important part, reference to the class that actually implements the plugin itself.
  • Plugin Interface(s) - (optionally) one or more interfaces that are implemented by the plugin. Only methods defined in these interfaces can be called by the plugin host application.
  • Plugin Implementation - a class that extends the com.remobjects.hydra.CrossPlatformVisualPluginBase and (optionally) implements the plugin interface(s).

Hydra for Java plugins can be created in any language that supports JVM as a target platform (Elements, Java, Kotlin etc). The only requirement is that this language should be able to produce .jar files. Any .jar file providing the parts mentioned above can be loaded by Hydra host application.

Hydra for Java is shipped with plugin project templates for all 4 Elements family languages. The next section will describe a newly created Visual Plugin project based on this template.

Note: Due to technology limitations Java GUI embedded directly into a WinForms or WPF window can be displayed not smooth enough. To avoid this the recommended approach is to embed as simple GUI as possible and to display more advanced GUI using native (ie non-embedded into the host form) Java UI dialogs.

Visual Plugin project review

This section contains a detailed review of Hydra for Java plugin project elements.

Plugin Descriptor

The purpose of this class is to provide the information required by a Hydra host application to properly load any use the plugin.

This class should implement the com.remobjects.hydra.PluginDescriptor interface contained in the com.remobjects.hydra.jar file shipped with Hydra for Java.

public class PluginDescriptor implements com.remobjects.hydra.PluginDescriptor {

    @Override
    public String getName() {
        return "Visual Plugin";
    }

    ...

    @SuppressWarnings("rawtypes")
    @Override
    public Class getPluginClass() {
        return PluginImplementation.class;
    }
}
type
  PluginDescriptor = public class(com.remobjects.hydra.PluginDescriptor)
  public
    property Name: String read 'Visual Plugin';
    property Description: String read 'Hydra for Java visual plugin';
    property UserData: String read '';
    property MajorVersion: Int32 read 1;
    property MinorVersion: Int32 read 0;
    property PluginClass: &Class read typeOf(PluginImplementation);
  end;
public class PluginDescriptor : com.remobjects.hydra.PluginDescriptor
{
    public string Name
    {
        get
        {
            return "Visual Plugin";
        }
    }

    ...

    public Class PluginClass
    {
        get
        {
            return typeof(PluginImplementation);
        }
    }
}
open class PluginDescriptor : com.remobjects.hydra.PluginDescriptor {
    public var Name: String! {
        get {
            return "Visual Plugin"
        }
    }

    ...

    public var PluginClass: Class! {
        get {
            return dynamicType(PluginImplementation)
        }
    }
}

As displayed above this class provides plugin metainformation like its name, description, version, as well as a reference to the class containing actual plugin implementation.

Plugin Implementation

This is a class that implements the plugin itself. This class is instantiated and embedded into the host window when plugin is loaded by a host application.

Plugin class should extend the com.remobjects.hydra.CrossPlatformVisualPluginBase class. This class implements the com.remobjects.hydra.HYCrossPlatformVisualPlugin interface thus providing the methods required by Hydra host applications to use the provided class instance as a visual plugin.

The code required to create Swing widgets should be placed into the plugin constructor.

Note: It is possible to create Java Visual Plugins using Java GUI other than Swing. In this case instead of extending the com.remobjects.hydra.CrossPlatformVisualPluginBase one will need to provide his own implementation of the com.remobjects.hydra.HYCrossPlatformVisualPlugin interface.

Using the Plugin

Loading Plugin

The following prerequisites have to be met to allow a host application to load Java plugins:

  • JVM installed. Its bitness should match the one of the host application. This means that if the host application is built as a x86 app then to load a Java plugin it will require a x86 version of JVM.
  • com.remobjects.hydra.jar file should be placed next to the host application assembly. This .jar file contains a Java code required to load and manage Hydra for Java plugins.

Note: The com.remobjects.hydra.jar file used to load Hydra for Java plugins should match the com.remobjects.hydra.jar file used to build the plugins.

Once prerequisites are met all what is required to load a Java plugin is to call the LoadModule method of the host's ModuleManager instance:

moduleManager.LoadModule("com.hydra.sample.visual.plugin.jar");
moduleManager.LoadModule('com.hydra.sample.visual.plugin.jar');
moduleManager.LoadModule("com.hydra.sample.visual.plugin.jar");
moduleManager.LoadModule('com.hydra.sample.visual.plugin.jar')

Note: Path to the .jar file should contain only alphanumeric symbols. In case it would contain chars like # plugin loading will fail with obscure Class not found message.

Displaying GUI

Once the plugin is loaded it can be displayed and used via the usual Hydra API.

At first the loaded plugin should be instantiated:

var pluginInstance = ((IBasePlugin)(module.CreateInstance(plugin)));
var pluginInstance := IBasePlugin(&module.CreateInstance(plugin));
var pluginInstance = module.CreateInstance(plugin) as IBasePlugin;
var pluginInstance = (module.CreateInstance(plugin) as? IBasePlugin)

Then it can be assigned to the host paned and displayed:

hostPanel.HostPlugin(pluginInstance);
hostPanel.HostPlugin(pluginInstance);
hostPanel.HostPlugin(pluginInstance);
hostPanel.HostPlugin(pluginInstance)

Custom Plugin Interface

Java Visual Plugin can provide custom interfaces and methods similar to Java NonVisual Plugins. Please refer to the corresponding article for more details.