JXMLPad 

Version 2.2

Site : http://www.japisoft.com/xmlpad  

Add queries, needs, bugs on this Forum
  : http://www.japisoft.com/forum/index.php


Tutorial 1 : Basic usage | Tutorial 2 : Creating a JSP editor

Features :

JXMLPad is a swing component for editing XML documents. You can get a registered royalty free version at : http://www.japisoft.com/buy.html

Insert JXMLPad in your application and minimize the cost of development or call to an XML editor.

I. Usage
II. Actions
III. Helper
IV. Status bar
V. LookAndFeel
VI. Component properties
VII.  XML integrity
VIII. Custom Node Editor
IX. Customize the parser
X. Known limitations

I. Usage

JXMLPad is composed of a main container and a set of elements :
  1. The main container : XMLContainer
  2. A default toolbar inside the XMLContainer
  3. A default popup inside the XMLContainer
  4. A default message location and error panel inside the XMLContainer
  5. One editor or two editors inside the XMLContainer : XMLEditor
  6. One tree view always synchronized with the text changes
  7. One element view synchronized with the tree selection

All default elements of the XMLContainer are externalizable. So user can have for sample its own ToolBar (I.e) or StatusBar.

Fast starting : Accessibility is a toolkit for setting/getting a text easily, calling an action... Accessibility is available by calling getAccessibility on the XMLContainer.

Sample :

XMLContainer container = new XMLContainer();
container.getAccessiblity().setText( "<test></test>" );

a. Toolkit usage

The toolkit provides a real facility for editing single or multiple XML documents.

com.japisoft.xmlpad.toolkit.SingleDocumentEditor.showEditor( "c:/conf.xml", false );


This sample line will show and edit the 'c:/conf.xml' document file. Note that this function returns a SingleDocumentEditor which is a javax.swing.JFrame frame and you can access to the XML component by calling the getXMLContainer method.

For multiple document usage, you must use the MultipleDocumentEditor.

com.japisoft.xmlpad.toolkit.MultipleDocumentEditor.showEditor( new File( "c:/tmp/xmlpad/xmlpad/samples/xml-data" ), null );

This sample line will show and edit all file under the xml-data directory. The null argument position is usely for a java.io.FileFilter rejecting file which name doesn't match a criteria.

b. Simple usage

Simple usage of JXMLPad is to integrate an XMLContainer inside your application as any swing component.

package demo;

import com.japisoft.xmlpad.XMLContainer;

import java.awt.*;
import javax.swing.*;

/** Simple component usage */
public class Demo extends JFrame {
    public Demo() {
        getContentPane().add( new XMLContainer() );
        setSize( new Dimension( 550, 400 ) );
        setTitle( "XMLPad simple demo" );
        setVisible( true );
    }

    public static void main( String[] args ) {
        new Demo();
    }
}


This sample create  a swing Frame with a JXMLPad content.

c. Application usage

Another way to integrate JXMLPad is to see it as a whole application. Most of applications contains a menu.
JXMLPad provides an action model with all available actions. This actions are shown inside the main toolbar.

package demo;

import com.japisoft.xmlpad.*;
import com.japisoft.xmlpad.action.*;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/** Simple usage of the <code>XMLContainer</code> toolbar action model
    @version 1.1
*/
public class Demo extends JFrame {

    public Demo() {
        XMLContainer mContainer = new XMLContainer();
        getContentPane().add( mContainer );
        setSize( new Dimension( 550, 400 ) );
        setTitle( "JXMLPad application demo" );
        resetMenu( mContainer.getToolBarModel() );
        setVisible( true );
    }

    private void resetMenu( ToolBarModel model ) {
        JMenuBar menuBar = new JMenuBar();
        JMenu file = new JMenu( "File" );
        menuBar.add( file );
        setJMenuBar( menuBar );

        // I retreive all Action instances from the
        // current ActionModel

        Action[] fileAction = new Action[] {
            ActionModel.getActionByName( ActionModel.NEW_ACTION ),
            ActionModel.getActionByName( ActionModel.LOAD_ACTION ),
            ActionModel.getActionByName( ActionModel.SAVE_ACTION ),
            ActionModel.getActionByName( ActionModel.SAVEAS_ACTION )
        };
        buildMenu( fileAction, file );
    }

    private void buildMenu( Action[] actions, JMenu menu ) {
        for ( int i = 0; i < actions.length; i++ ) {
            JMenuItem item = ( JMenuItem )menu.add( actions[ i ] );
            item.setText( "" + actions[ i ].getValue( "ACTION.NAME" ) );
        }
    }
}


In this sample, we build a minimal application with a file menu. We retreive all action by the ActionModel class. This
class contains a model with a set of ActionGroup. Each ActionGroup contains a set of XMLAction. A group defines a
collection of action that are similar like cut, copy and paste action. Visually, a group is seen by a separator inside the
main toolbar.
Each action from the ActionModel has a name, by default the ActionModel contains several action with static variable like the
NEW_ACTION.

d. Applet usage

Another way to use JXMLPad is an applet usage. This applet usage needs a browser compatible with the java plug-in technology like internet explorer or netscape.

Here a sample of applet

package demo;

import javax.swing.*;

import com.japisoft.xmlpad.XMLContainer;

/** Here an applet demonstration usage with JXMLPAD */
public class AppletDemo extends JApplet {

        public AppletDemo() {
                super();
                initUI();
        }
       
        private void initUI() {
                getContentPane().add( new XMLContainer() );
        }

}


Here an HTML page using JXMLPad

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<!-- @(#)SwingApplet.html       1.1 97/07/02 -->
<html>
<body>

<!-- HTML CONVERTER -->
<OBJECT
    classid="clsid:CAFEEFAC-0014-0000-0001-ABCDEFFEDCBA"
    WIDTH = "600" HEIGHT = "400" 
    codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4_0_01-win.c
ab#Version=1,4,0,10">
    <PARAM NAME = "CODE" VALUE = "demo.AppletDemo" >
    <PARAM NAME = "ARCHIVE" VALUE = "../lib/xerces.jar,../lib/xm
lpad.jar" >
    <PARAM NAME = "JAVA_CODEBASE" VALUE = "classes">
    <PARAM NAME="type" VALUE="application/x-java-applet;jpi-version=1.4.0_01">
    <PARAM NAME="scriptable" VALUE="false">

    <COMMENT>
        <EMBED
            type="application/x-java-applet;jpi-version=1.4.0_01"
            CODE = "demo.AppletDemo"
            ARCHIVE = "../lib/xerces.jar,../lib/xmlpad.jar"
            JAVA_CODEBASE = "classes"
            WIDTH = "600"
            HEIGHT = "400" 
            scriptable="false"
            pluginspage="http://java.sun.com/products/plugin/index.html#download">
                <NOEMBED>
               
                </NOEMBED>
        </EMBED>
   </COMMENT>
</OBJECT>

<!--
<APPLET CODE = "demo.AppletDemo" CODEBASE="res" ARCHIVE = "../lib/xerces.jar,../lib/xmlpad.jar" WIDTH = "600" HEIGHT = "400">
</APPLET>
-->

<!--"END_CONVERTED_APPLET"-->

</body>
</html>


That that you may have changes on the ARCHIVE, JAVA_CODEBASE section for getting a valid path to the JXMLPad libraries and your applet ressources.

e. Multiple editor usage

In a multiple editor usage like inside a JTabbedPane, it is necessary to have only one common toolBar.

Here a sample from the MultipleDocumentEditor:

public class MultipleDocumentEditor extends JFrame implements ChangeListener {
    private JToolBar toolBar;
    private JTabbedPane tabbedPane;

    private MultipleDocumentEditor() {
        super( "Multiple editor" );
        // Connection listeners for adapting the ActionModel to the current XMLContainer
        tabbedPane.addChangeListener( this );
    }

    public void stateChanged(ChangeEvent e) {
        XMLContainer container = ( XMLContainer )tabbedPane.getSelectedComponent();
        ActionModel.resetActionState( container.getEditor(), container );
    }

    public static MultipleDocumentEditor showEditor( String[] files ) throws FileNotFoundException, IOException {
         ...
        ActionModel.buildToolBar( frame.toolBar );
   
        // Build all containers
        for ( int i = 0; i < files.length; i++ ) {
            XMLContainer container = new XMLContainer();
            container.setToolBarAvailable( false );
            ...
        }
...

}


The showEditor method will add several XMLContainer in a JTabbedPane. Here the interesting step :

  1. Add a listener for resetting the ActionModel to the current XMLContainer. It will notify all XMLAction that they must work on another XMLContainer.
  2. On each change event from a tabbedPane selection, reset the Action state calling resetActionState
  3. Build the common toolbar calling buildToolBar
  4. Disable the default XMLContainer toolbar calling setToolBarAvailable( false )

f. Internal frame usage

JXMLPad maintains several inner references that can't be garbaged. By default JXMLPad uses a special mode for removing all this references as possible. This special mode is called "AutoDisposeMode" and is available as a property in the XMLContainer. For Internal Frame usage, this mode must be disabled. The developper will have to call dispose after each XMLContainer usage.

public class InternalFrameSample implements WindowListener {

   public void windowActivated(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}

    public void windowClosing(WindowEvent e) {
// Freeing all inner resources
editor1.dispose();
editor2.dispose();
}

    public void windowDeactivated(WindowEvent e) {}
    public void windowDeiconified(WindowEvent e) {}
    public void windowIconified(WindowEvent e) {}
    public void windowOpened(WindowEvent e) {}

    public InternalFrameSample() {
init();
}

    private XMLContainer editor1;
    private XMLContainer editor2;

    public void init() {
        JFrame frame = new JFrame();
        frame.addWindowListener( this );
        JDesktopPane dp = new JDesktopPane();

        // Add two inner frame

        JInternalFrame editorFrameOne = new JInternalFrame();
        editorFrameOne.setTitle( "My editor 1" );
        // This constructor avoids XMLContainer for freeing automatically its inner reference
        editor1 = new XMLContainer( false );
        editor1.setText( "<?xml version='1.0'?>\n<test></test>" );
        editorFrameOne.getContentPane().add( editor1 );
        editorFrameOne.setResizable( true );

        dp.add( editorFrameOne );
        editorFrameOne.setSize( 200, 200 );        
        editorFrameOne.setVisible( true );
        editorFrameTwo.setVisible( true );      

        frame.getContentPane().add( dp );
        frame.setSize( 400, 400 );
        frame.setVisible( true );
    }

II. Actions

a. Definition

As we begin to see previously, a toolbar is composed of action inheriting from the XMLAction class. An XMLAction is
stored inside an ActionGroup. An ActionGroup is stored itself inside an ActionModel. Each time an editor has focused from the
XMLContainer, all actions from the ActionModel are adapting for working on the good editor by calling setXMLEditor and setXMLContainer. You don't need to override this methods, but rather notifyXMLContainer and notifyXMLEditor. So if you wish to use actions with a tabbed pane system (I.e), you will have to reset action for each tabbed pane change. If you want to add action for the realtime tree you must inherit from AbstractTreeAction which inherits itself from the XMLAction.

From your the ActionModel you can :
Each action has a default name, tooltip, accelerator, mnemonic, icon and group. Each value can be overrided using a
Property file (look at b.6). A group is a way to create subMenu for popup. Assuming an action would like to be a part
of the Edit popup menu, it will just have to override getPopupGroup and return Edit.

Note that the main toolbar has itself an action model.  This action model can be retreived calling getToolBarModel on the
XMLContainer. If you remove or add a XMLAction , it will be handled in real time. By default the action model contains the
ActionModel content. This is the same case for the popup on the text and on the tree. Here a sample changing it :

XMLContainer container = new XMLContainer();
// Remove the NEW_ACTION for the default toolbar only for THIS container
container.getToolBarModel().removeAction( ActionModel.getActionByName( Action.NEW_ACTION ) );
// Add a new one for THIS container
container.getPopupModel().addAction( myNewAction() );
// Add another one on the tree for THIS container
container.getTreePopupModel().addAction( myTreeAction() );

b. Usage

1. Replacing existing default action by your action
ActionModel.replaceActionByName(ActionModel.NEW_ACTION, new NewAction() );

// Here my New action that write a default JSP page
class NewAction extends XMLAction {
        public NewAction() {
            // Get the same icon than the default New action
            super( ActionModel.NEW_ACTION );
        }
       
        public void notifyXMLContainer() {
          // Initializing the action for this container ?
          // setEnabled( ... )
        }

        public void notifyAction() {
            container.setText( "<%@page language=\"java\"%>\n" +
                            "<html>\n" +
                            "<body>\n" +
                            "</body>\n" +
                            "</html>" );
        }

        public String getName() {
            return ActionModel.NEW_ACTION;
        }
}

2. Disabled/Enabled current action
// Disable the parse and format action
ActionModel.setEnabledAction( ActionModel.REFRESH_ACTION, false );
ActionModel.setEnabledAction( ActionModel.FORMAT_ACTION, false );

3. Invoke an action
// run the new action
ActionModel.activeActionByName(ActionModel.NEW_ACTION);

you can also active an action for another component context calling

// run the new action on another component
ActionModel.activeActionByName(ActionModel.NEW_ACTION, myXMLContainer, myXMLEditor );
4. Properties file definition
You can customize your toolbar with a xmlpad.properties file that must be inside your classpath.

factory=com.japisoft.xmlpad.ComponentFactory
look=com.japisoft.xmlpad.look.MozillaLook
tree=true
location=true
fontname=Dialog
fontsize=12
action.file.1=com.japisoft.xmlpad.action.NewAction
action.file.2=com.japisoft.xmlpad.action.LoadAction
action.file.3=com.japisoft.xmlpad.action.SaveAsAction
action.edit.1=com.japisoft.xmlpad.action.CutAction
action.edit.2=com.japisoft.xmlpad.action.CopyAction
action.edit.3=com.japisoft.xmlpad.action.PasteAction
groupOrder=file,edit

The syntax for an action definition is : action.GROUP.ORDER=YOUR_CLASS

Here I define two action group : file and edit. Each number is for the position, thus the NewAction will be at the first place followed by the LoadAction.  The groupOrder defines an order for each group, in this sample the file group will be added before the edit group.
5. New actions
Rather than using the xmlpad.properties file for adding new actions, you can add it from the ActionModel.

Here a sample :  I add a new action MyNewAction that inherits fromXMLAction.

ActionModel.addActionForGroup( ActionModel.EDIT_GROUP, new MyNewAction() );

It will add in the edit group the MyNewAction. Such action will be now visible in the main toolbar. You can define your own
group just by choosing any group name.

Notes :

- The icon for your action is always found from the classpath in the same package of your action your class name adding '16.gif' or '24.gif'. From sample, the com.japisoft.xmlpad.action.file.NewAction has its default images here : com/japisoft/xmlpad/action/file/NewAction16.gif and com/japisoft/xmlpad/action/file/NewAction24.gif.

- You can override the default Icon location with the getDefaultIcon method.

- Calling setActionReferenceIcon you can have the same icon than another known action.
6. Internationalization
Each XMLAction have property file containing :
You can override any value by wrting a property file matching an Action class name and with a precedence inside the
classpath.

Here a sample override the default Copy action to a french version :

I create a com/japisoft/xmlpad/action/edit/CopyAction.properties or I update the default one :

LABEL=Copie
TOOLTIP=Copier la sélection courante
ACCELERATOR=ctrl C

Note : Dialog box have also property file for title and help

Here a sample for the comment dialog located at : com/japisoft/xmlpad/action/xml/CommentAction$CommentDialog.properties

 # Comment dialog, you can override these values

TITLE=Comment
COMMENT=Insert an XML comment. This comment can contain several lines
OK=Comment it
7. UIManager for changing the look
Please look at the IV. b section for available properties.

c. Default actions

Here available actions :

Name
ActionModel Default
Role
New
Yes
Build a new XML document. This action uses the XMLTemplate class for building a new page.
Load
Yes Load an XML document
SaveAs
Yes Save an XML document
Copy
Yes Copy a text
Cut
Yes Cut a text
Paste
Yes Paste a text
Undo
Yes Undo the last action but this is a new document action
Redo
Yes Redo the last action but to undo action has been called
Parse Yes Parse the current document and show any error in red
Search
Yes Parse the current document and show a tree for easily navigating
Split
Yes Split the current editor in two ones
Format
Yes Ident the current XML text.
Tree visibility
False
Show/Hide the realtime tree
Copy node
Yes
Copy the current tree node
Cut node
Yes
Cut the current tree node
Comment node
Yes
Comment the current tree node
Select node
Yes
Select the current tree node in text
Edit node
Yes
Use the editor model : VIII

III. Helper

Completion is available for two usages :

The Helper API is built around the SyntaxHelper class. The current instance is available by calling getSyntaxHelper on the XMLContainer.

This syntaxHelper works in two ways :
  1. By reading a DTD (relative to the current document or not). This DTD can be provided calling the setDefaultDTD or setDTD of the XMLContainer or directly inside the SyntaxHelper. This DTD will be automatically read in your current XMLDocument each time it is saved, loaded or parsed. The DefaultDTD is used is no DTD is found in the current document.
  2. By reading a Schema (relative to the current document or not). This Schema can be provided calling the setDefaultSchema or setSchema of the XMLContainer. This schema will be automatically read in your current XMLDocument each time it is saved, loaded or parsed.
  3. By reading a RelaxNG grammar. This grammar is set by calling setRelaxNGValidationLocation on the XMLContainer. Once the grammar (XML form) provided, completion and parsing will use relaxNG but there's a current schema or DTD.
  4. By using a static document descriptor. This descriptor is not available directly. User have to call the addTagDescriptor method on the SyntaxHelper.
Usage sample for DTD :

I have declared this DTD by building a jsp.dtd file  :

<!-- Here a minimal DTD for JSP page -->

<!ELEMENT html (head,body)>
<!ELEMENT head (title)>
<!ELEMENT title #PCDATA>
<!ELEMENT body (jsp:include|jsp:getProperty|jsp:setProperty|jsp:useBean)>

<!ELEMENT jsp:include EMPTY>
<!ATTLIST jsp:include
  page CDATA #REQUIRED>

<!ELEMENT jsp:getProperty EMPTY>
<!ATTLIST jsp:getProperty
 name CDATA #REQUIRED
 property CDATA #REQUIRED>

<!ELEMENT jsp:setProperty EMPTY>
<!ATTLIST jsp:setProperty
  property CDATA #REQUIRED
  value CDATA #REQUIRED>

<!ELEMENT jsp:useBean EMPTY>
<!ATTLIST jsp:useBean
  id CDATA #REQUIRED
  scope CDATA #REQUIRED>


Here a way to force usage because my document has no DTD header :

container.setDefaultDTD( "html", "jsp.dtd" );

If your document contains a DOCTYPE part, there's no reason to force a default usage. Morever, the
DTD will be found relativly to the current document location (similar handling for schemas).

For remarks :

- A Default DTD has no usage when you declare a valid XML header like :
<!DOCTYPE Module SYSTEM "file:///home/japisoft/test/project/myDTD.dtd">

- The DTD header handling is made while saving, loading or parsing. However you can force it by calling the searchAndParseDTD on the XMLContainer. This is similar for schema by calling searchAndParseSchema on the XMLContainer.

- To remove RelaxNG grammar jut call setRelaxNGValidation( null )

IV. Status bar

JXMLPad has its own status bar inside the XMLContainer component. However, user may want an external toolbar showing
the current XPath location.

Here a sample that uses a minimal external status bar :

public class Demo extends JFrame implements LocationListener {
    private JLabel sb;

    public Demo() {
    XMLContainer container;
    getContentPane().add( container = new XMLContainer() );
    getContentPane().add( sb = new JLabel( "..." ), BorderLayout.SOUTH );

    setSize( new Dimension( 550, 400 ) );
    setTitle( "XMLPad statusbar demo" );

    // Disable the inner statusbar
    container.setStatusBarAvailable( false );
    // Connect the listener for location
    container.addLocationListener( this );
    setVisible( true );
    }

    public void locationChanged( LocationEvent e ) {
        sb.setText( e.getXPathLocation() );
    }
}


With the LocationListener event, user receives each time the caret is changed the XPath location. Note it is necessary to
remove the default status bar by calling setStatusBarAvailable( false ) else two status bars would be visible.

V. LookAndFeel

a. The Look interface

JXMLPad has a lookAndFeel plug-in system for :

- The syntax coloration,
- The default XML content,
- The real tree renderer.


A set of themes are also availabe from the com.japisoft.xmlpad.look.themes package. Here a sample for using it :


GreenTheme.install();
JFrame fr = new JFrame();
XMLContainer container = new XMLContainer();
//We don't want the element view
//container.setElementView( null );
fr.getContentPane().add( container );
fr.setSize( 300, 300 );
fr.setVisible( true );

For defining or updating a theme, look at the UIManager section for a complete properties listing. Note that the following Look and Feel system will be deprecated. We advise you to use the UIManager for commodity

Here a sample from the default lookAndFeel :

package com.japisoft.xmleditor.look;

import java.awt.*;
import com.japisoft.xmleditor.bean.XMLEditor;
import com.japisoft.xmleditor.bean.XMLTemplate;

/**
 * Default look for the <code>XMLEditor</code>
 *
 * @author (c) 2002 JAPISoft
 * @version 1.0
 * @see Look
 * @see LookManager */
public class DefaultLook implements Look {

    public DefaultLook() {
        super();
    }

    public void install( XMLEditor editor ) {

        editor.setErrorLineColor( new Color( 200, 0, 0 ) );
        // Syntax Colorization
        editor.setCommentColor( new Color( 255, 0, 0 ) );
        // <? and <!
        editor.setDeclarationColor( Color.gray.darker() );
        editor.setDocTypeColor( Color.gray.darker() );
        editor.setTagColor( Color.green.darker().darker() );
        editor.setLiteralColor( Color.blue );

        // Tag delimiter
        editor.setTagDelimiterHighlight( true );
        editor.setTagDelimiterHighlightColor( editor.getTagColor().brighter() );

        // Att delimiter
        editor.setAttDelimiterHighlight( true );
        editor.setAttDelimiterHighlightColor( new Color( 100, 100, 150 ) );

        editor.setCaretColor( Color.black );
         editor.setEntityColor( Color.blue );

        editor.setSelectionLineColor( new Color( 150, 150, 230 ) );

        editor.setBackground( Color.lightGray );
        editor.setForeground( Color.black );

        editor.setDeclarationFont( new Font( null, Font.BOLD, 10 ) );
        editor.setDocTypeFont( new Font( null, Font.BOLD, 10 ) );

        editor.getCaret().setBlinkRate( 500 );

        // Template

        XMLTemplate template = new XMLTemplate();
        template.setComment( " Version : 1.0, Date : " + new java.util.Date() );
        editor.setTemplate( template );
    }

    public void uninstall( XMLEditor editor ) {

    }
}

This default look is installed by calling (before any "new XMLContainer" !):

LookManager.setCurrentLook( new com.japisoft.xmleditor.look.XMLPadLook() );

This must be done before the new XMLContainer usage, otherwise you can dynamically
change the look by calling the LookManager.install( Editor ).

Note : One mere way to create your own LookAndFeel is by overriding an existing one (like the MozillaLook) and updating only what you prefer.

Known looks :

com.japisoft.xmlpad.look.XMLPadLook
The default one
com.japisoft.xmlpad.look.MozillaLook
A very similar look than the default one except on the tree part
com.japisoft.xmlpad.look.IELook
An "Internet explorer" look

b. UIManager

User can control all the JXMLPad appearance using the javax.swing.UIManager with the following properties. Note that
the UIManager must be used before the building of the XMLContainer.

For the editor :

xmlpad.editor.font
xmlpad.editor.dtdElementColor
xmlpad.editor.dtdAttributeColor
xmlpad.editor.dtdEntityColor
xmlpad.editor.tagBorderLineColor
xmlpad.editor.cdataColor
xmlpad.editor.entityColor
xmlpad.editor.commentColor
xmlpad.editor.declarationColor
xmlpad.editor.docTypeColor
xmlpad.editor.literalColor
xmlpad.editor.tagColor
xmlpad.editor.invalidColor
xmlpad.editor.textColor
xmlpad.editor.attributeColor
xmlpad.editor.attributeSeparatorColor
xmlpad.editor.selectionHighlightColor
xmlpad.editor.backgroundColor

ex : UIManager.put( "xmlpad.editor.tagColor", Color.red );

For the tree :

xmlpad.tree.font
xmlpad.tree.elementIcon
xmlpad.tree.textIcon
xmlpad.tree.errorIcon
xmlpad.tree.textColor
xmlpad.tree.selectionColor

ex : UIManager.put( "xmlpad.tree.font", new Font( null, 0, 10 ) );

For the element view :

xmlpad.tableElementView.font
xmlpad.tableElementView.prefixNameColor
xmlpad.tableElementView.highlightColor
xmlpad.tableElementView.highlightColor
xmlpad.tableElementView.lowlightColor

For the action :

xmlpad.action.[FULL ACTION CLASS NAME].mnemonic (a string)
xmlpad.action.[FULL ACTION CLASS NAME].accelerator(a string)
xmlpad.action.[FULL ACTION CLASS NAME].label
xmlpad.action.[FULL ACTION CLASS NAME].tooltip
xmlpad.action.[FULL ACTION CLASS NAME].icon

ex : UIManager.put( "xmlpad.action.com.japisoft.xmlpad.action.file.LoadAction.icon", new ImageIcon( "/tmp/icon.gif" ) );

For the popup helper:

xmlpad.helper.backgroundColor
xmlpad.helper.foregroundColor
xmlpad.helper.selectionBackgroundColor
xmlpad.helper.selectionForegroundColor
xmlpad.helper.icon

ex : UIManager.put( "xmlpad.helper.backgroundColor", new Color( 240, 250, 230 ) );

For remarks : you must use UIManager.setString for the mnemonic and the accelerator of your action. JXMLPad has a set of color theme available from the com.japisoft.xmlpad.look.themes.

VI. Component properties

The XMContainer is highly customizable. One easy way to change a part if the 'xmlpad.properties' file localized by default
in the '/lib' directory.

Here the default content :

factory=com.japisoft.xmlpad.ComponentFactory
look=com.japisoft.xmlpad.look.MozillaLook
tree=true
location=true
fontname=Dialog
fontsize=12

Property name
Property role
Default value
factory
Components for the XMLContainer like the toolbar, the editor...
com.japisoft.xmlpad.ComponentFactory
look
The Default lookAndFeel
com.japisoft.xmlpad.look.XMLPadLook
tree
Show the real time tree
true
location
Localize the current cursor in the tree
true
fontname
Font name
Dialog
fontsize
Font size
12

VII.  XML integrity

Integrity API part a way to maintain a valid XML document.

Integrity occurs in :
  1. Avoiding to corrupt XML tag. So in such mode, user cannot modify current tags but is it always possible to modify other XML part
  2. Checking if a saved document is valid by parsing it. If the document is not valid, the document cannot be saved. 
You can force control of the XML integrity by using the XMLIntegrity class. This class is available by the XMLContainer/getDocumentIntegrity method.

VIII. Custom Node Editor

In some context, you don't wish for confort reason edit a part of the document in the text part and you wish an external editor showing your XML data in a better view. This is possible with the JXMLPad API inside the com.japisoft.xmlpad.editor package.
This particular editing view is available inside the left tree using the Popup and the "Edit" action.

This package is built with these elements :

- The Editor interface
- The EditorContext
- The EditorModel
- The DefaultEditor

The first one is an interface your custom node editor must implement. This interface has two main methods : An accept method where the editor decides if it accepts to edit such node or not and an editmethod where the real editing action is done when the user clicks the "edit" action. Inside the edit method, an EditorContext is provided with an access to the current node and text. The role of the edit method is to write the new text result inside the EditorContext calling setResult.

When you build a new custom node editor, you must declare it inside the EditorModel by calling addEditor. This model will add your custom editor with a highter priority than the last added.

Here a sample of the default test editor :

public class DefaultEditor implements Editor {

    /** Accept all text node : by checking <code>isText</code> */
    public boolean accept(SimpleNode node) {
        return ( node.isText() );
    }

    /*
     * Edit a text node by showing a Text dialog
     */
    public void edit(EditorContext context) {
        XMLContainer container = context.getXMLContainer();
        ...
        context.setResult( dialog.getText() );
    }
}

For note : It is also possible since the 2.0RC5 to call an editor outside the Edit menu popup by calling editCurrentNode from the XMLContainer class.

IX. Customize the parser

JXMLPad uses JAXP (Java API for Xml Processing) for parsing or formatting a document. Thus, any parser compliant with JAXP can be used.

"Different vendors provide different implementations of this abstract class. Java chooses the one to use based on the following conditions in order of preference:

  1. The value of the javax.xml.parsers.DocumentBuilderFactory Java system property

  2. The value of the javax.xml.parsers.DocumentBuilderFactory property specified in the lib/jaxp.properties properties file in the JRE directory

  3. The first value found in a META-INF/services/javax.xml.parsers.DocumentBuilderFactory file in the JAR files available to the runtime

  4. The platform default (org.apache.crimson.jaxp.DocumentBuilderFactoryImpl in Sun’s JDK 1.4)."

X. Known limitations

- Font changes for XML element (like tag name) shouldn't be used with editable state Component.
- Real time text / tree location doesn't take into account of multiple current tag occurrence.



(c) 2002 - 2003 JAPISOFT / Alexandre Brillant