Developer Guide

Author: Damien Guillaume

Introduction

Although Jaxe has been localised to English, most of the source code is using French, and most comments, variables, methods, and classes are in French. So, knowing French can be useful to develop with Jaxe, but it is not necessary in most cases, since you can just follow the following recipes. Also, most CVS update comments on sourceforge are in English, so it's also useful to know English. But the language you really have to know is of course Java !

It will be assumed that the reader has already read the documentations for users, administrators and the syntax for configuration files.

This documentation explains how to use Jaxe within another application, and how to add plugins to display elements.


Using Jaxe within another application

Jaxe's startup class is (unsurprisingly) jaxe.Jaxe. This class gathers external events handling (file opening, closing, etc...), so it can be useful to take a look at it to see how a new Jaxe document is created or opened.

Another important class is jaxe.JaxeFrame. This class relates to an XML document window. It is using the class jaxe.JaxeMenuBar to handle the menubar, this one being unfortunately (because of a shortcoming of Java) linked to the window.

The easiest way to include Jaxe in another application is probably to use the class jaxe.JaxeTextPane, which represents the text area in the XML window. Since this class is derived from java.swing.JTextPane, it can easily be added wherever required, according to the host application layout. The constructor requires a JaxeDocument (linked to the DOM) and a JFrame (the parent window).

The object of class jaxe.JaxeDocument has to be initialised with a Jaxe configuration file (handled by the class jaxe.Config) and possibly with an XML file or with a DOM object.

To sum up, here is a list of instructions to include a Jaxe text area in a parent Container located in a given frame:

JaxeDocument jaxeDoc = new JaxeDocument("mylanguage_config.xml");
JaxeTextPane jaxeTextPane = new JaxeTextPane(jaxeDoc, frame);
jaxeDoc.lire(xmlFileURL);
// or jaxeDoc.setDOMDoc(domDocument);
parent.add(jaxeTextPane);

Elements can be inserted with the contextual menu, or with jaxe.ActionInsertionBalise actions. The constructor for ActionInsertionBalise requires the Jaxe document, and the DOM element corresponding to the definition of the element in the Jaxe configuration file.

The document can later be saved with the method JaxeDocument.ecrire(File f).


Creation of new Jaxe elements

A Jaxe element is a class derived from jaxe.JaxeElement, describing a display for a given XML element. Standard Jaxe elements are gathered in the jaxe.elements package. They correspond to display types in the configuration files (for instance, the type string corresponds to the Jaxe element jaxe.elements.JEString).

A new Jaxe element can be created by deriving a new class from jaxe.JaxeElement. It can then be used in a configuration file with the plugin type, with the class to be used:

<AFFICHAGE_ELEMENT element="aBooleanElement" type="plugin">
  <PARAMETRE nom="classe" valeur="JEBoolean"/>
</AFFICHAGE_ELEMENT>

Two methods must be defined in the Jaxe element: init and nouvelElement. Two other ones are only useful if starting and ending tags are used (as explained later): insPosition, and (if the element has attributes) majAffichage.

init is used for initialisation and to insert the Swing component in the text area. The parameters are the position where the element has to be inserted in the text, and the DOM node. Using these parameters, the component has to be inserted with the method JaxeElement.insertComponent(Position pos, JComponent comp).

It gets trickier if we want to use a component as a start tag and a component as an end tag, letting Jaxe handle recursively the descendants. The position in the text after the insertion of the start tag has to be obtained (it is returned by insertComponent), descendants have to be added with creerEnfants(Position), and the end tag has to be inserted with a new call to insertComponent (with the Position objects passed as a parameter to creerEnfants. The character style has then to be updated for the tags and the descendants, which means the start position had to be kept before the first insertComponent. Here is an example:

int startOffset = pos.getOffset();
Position newpos = insertComponent(pos, startTagComponent);
creerEnfants(newpos);
insertComponent(newpos, endTagComponent);
if (newpos.getOffset() - startOffset - 1 > 0) {
  SimpleAttributeSet style = attStyle(null);
  if (style != null)
    doc.setCharacterAttributes(startOffset, newpos.getOffset() - startOffset - 1, style, false);
}

The method nouvelElement is called when the user inserts a new element. It might have to ask for informations to the user (such as the attributes), and has to return the new DOM element. The dialog jaxe.DialogueAttributs can be used to ask for attribute values.

insPosition can be called to get the position where the cursor will be placed after the insertion of a new element. By default, the cursor is placed after the element, but it can be useful to place it between the start and end tags when they are used.

Finally, majAffichage is called to update the display when the attributes values have been changed in the attribute panel.

Example

The following file is a Jaxe element for a boolean, using a checkbox as a display: JEBoolean.java. It can be compiled and put into a jar file to become a new plugin for Jaxe.


Adding a function

It is easy to add a menu launching a particular function instead of inserting an element. For this, one just needs to derive a class from jaxe.Fonction and implement the method appliquer, which provides the working Jaxe document, and the starting and ending positions of the text selection.

public void appliquer(JaxeDocument doc, int start, int end)

The DOM document can be obtained from the Jaxe document with doc.DOMdoc. A Jaxe element can be obtained from a position in the text with doc.elementA(int pos). All the elements in the interval [start,end] can be obtained with rootJE.elementsDans(start, end). The corresponding DOM node is obtained with JaxeElement.noeud.

Example

The following example adds a menu giving statistics about the document.

<MENU nom="plugins">
  <MENU_FONCTION classe="pluginsjaxe.StatisticsFunction" nom="Statistics"/>
</MENU>