# Developer Guide

Author: Damien Guillaume

- Introduction
- Using Jaxe within another application
- Creation of new Jaxe elements
- Adding a function

# 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.

- Download StatisticsFunction.java.
- Put it in a folder named `pluginsjaxe` (it's the name of the package).
- Compile it. From the location of the pluginsjaxe folder, type on the command line : `javac -encoding ISO-8859-1 -classpath .:lib/Jaxe.jar pluginsjaxe/StatisticsFunction.java` (assuming `Jaxe.jar` is in a `lib` directory under the working directory). This should create a file `StatisticsFunction.class` in the folder `pluginsjaxe`.
- Create a jar file with the folder `pluginsjaxe`, and add it to the `plugins` folder.
- Update the configuration file to add a menu calling the function:

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