Extending GroIMP
A collection of tutorials to create additional features for GroIMP.
Creating a Plugin
This tutorial aims at showing how to get started on GroIMP plugin development. It is assumed that you are able to compile the plugin using Maven (either the plugin alone, or the whole project). In this tutorial we are going to create a new plugin (from the empty template), add a new MimeType (format of file accepted by GroIMP) for import, and add a menu item that run a specific command.
See:
Includes object in production
XL rules can include a production statement, in which some Node and Edges are created (and possibly added - depends on the rule).
The production statement is managed by a Producer object. By default, RGG files use a RGGProducer.
Add templates and examples
The CLI and the API use the same way to load examples and templates, this way is different from the way currently used in the gui. Therefore the examples and templates added as follows will not show in the GUI.
For the CLI and the API a template or an example is just a .gsz file that is added to the registry.
It is possible to add examples and templates to an existing plugin or to create a simple new one.
Create new API functions
New GroIMP commands that work with the API can be created in any plugin. This small guide will only create a first starting point, for further information the code of the API plugin should be considered.
This does only work with the API plugin version >=0.2
Creating new mimeType and File type
Create windows
There are many level of windows that can be created in GroIMP, depending on the needs.
How to create a node class
Creating an own Java node class is not difficult. The new class, say Cube, has to be a subclass of _de.grogra.graph.impl.Node_ or one of its subclasses. So we have to write something like
import de.grogra.graph.impl.Node; public class Cube extends Node { }
However, we also would like our new cube to have a width-attribute. We add this in the usual way:
public class Cube extends Node { float width = 1; }
So far, this attribute is not registered with the UI and persistence mechanism of GroIMP. It will not be shown in the GUI, and it will not be saved or restored when a cube is written to or read from a data stream. We have to add special “comments” which are actually comments for the Java compiler, but read as input for the Perl script enhance.pl which is part of the Build project of the source distribution of GroIMP.
public class Cube extends Node { float width = 1; //enh:field getter setter //enh:insert }
The enh:field tag tells the script that the previously declared field has to be added to the persistence mechanism of GroIMP so that it is saved and restored as part of a cube. The tag also commands the script to create getter- and setter-methods. It is important that the enh:field tag immediately follows the field declaration and is not split into several lines. The enh:insert tag defines the location where the script shall insert the generated Java code. This has to be the last tag and should be placed at the end of the file. See this page for more information on the code enhancer.
Creating a new Plugin
JEdit plugins for GroIMP
The embedded text editor jEdit has some additional plugins not included in the GroIMP version.
They can be downloaded on the jEdit website.
Create embedded documentation based on markdown files
With GroIMP 2.1.4 it is possible to use a markdown file to generate the content of the embedded documentation of a GroIMP plugin. The idea is that the README.md file of a git repository is then doubly used. Yet since the pipeline depends on pandoc, it is in theory also possible to use a large number of other import formats including docx,odt or latex.
Translating GroIMP into other languages
Help to translate GroIMP into other languages is welcome. The steps needed to do so are simple. Every project contains a file src/plugin.properties
which stores the text messages displayed in the GUI. To translate those messages into another language, a copy of the file must be made and each message must be replaced by the correct translation.
To figure out the correct language to be displayed, the current locale of the system is used to construct a filename. Specifically the method ResourceBundle.getBundle is called, where baseName
is “plugin” and locale
is Locale.getDefault()
, the current locale set up for the system. The extension “.properties” is appended by that function automatically. For instance, if one would want to provide a translation into German, the filename should be plugin_de.properties
. If one would want to provide different translations for British and American English, the filenames would be plugin_en_UK.properties
and plugin_en_US.properties
. Here the en
is the *language code* and the UK
and US
are the *country codes*. A list of valid *language codes* can be found in ISO 639-1 and a list of valid *country codes* can be found in ISO-3166.
The plugin.properties
file contains key-value-pairs mapping from some identifier to some text, for instance:
/renderers/3d/ray2.Name = Twilight /renderers/3d/ray2/threadcount.Name = Number of threads /renderers/3d/ray2/brightness.Name = Global brightness /renderers/3d/ray2/rayprocessor.Name = Ray processor
Only lines in which the key ends in “.Name” should be translated. A translation of these lines into German would look like this:
/renderers/3d/ray2.Name = Twilight /renderers/3d/ray2/threadcount.Name = Anzahl der Kontrollflüsse /renderers/3d/ray2/brightness.Name = Globale Helligkeit /renderers/3d/ray2/rayprocessor.Name = Strahlenprozessor
Some names describing menu entries contain the &-sign to define an accelerator, for instance:
/objects/3d/geometry/primitives/box.Name = &Box
Pressing Alt+B
allows selecting this menu entry. When translating such lines care should be taken that no two menu entries visible at the same time define the same accelerator if possible.
To use a specific language translation either the locale of your computer must be set to that language, or you can select whatever language you like by running GroIMP like this:
java -Duser.language=de -jar core.jar
For some languages (like Chinese) Unicode Escapes must be used. The reason for this is, that the class PropertyResourceBundle is used by ResourceBundle
to read the file, and PropertyResourceBundle
requires the file contents to be encoded in ISO-8859-1. As explained in the Java Internationalization FAQ, there is a native2ascii
tool that converts from other encodings to ASCII by replacing non-ASCII characters by the appropriate escape sequence. The useful Eclipse plugin JInto is a property file editor that can directly edit property files written in Unicode reference characters, and saves the time and effort of converting into Unicode through native2ascii.
Java includes Unicode fonts, unfortunately if you are on a western system with western Java, these fonts do not support Chinese, Japanese, or Korean yet. Therefore you may need to install proper fonts and to tell Java which font should be used to display. For sun Java you can check JAVA_HOME/jar/lib/fontconfig.<OS-Name>.properties.src
for details which font Java (currently) wants to use.