JXMLPad 

Version 1.9.4
http://www.japisoft.com

Tutorial 1: Creating a JSP editor

Features :

JXMLPad is a swing component for managing XML documents. This is a royalty free shareware library for registered version.
You can get a registered version for a low price at : http://www.japisoft.com/buy.html

Insert JXMLPad in your application and reduce the cost of development of an XML editor.

I. Usage

JXMLPad is composed by 3 elements :
  1. The container : XMLContainer
  2. A toolbar
  3. One main editor : XMLEditor
The container managed both the toolbar and one or several editors.

a. Toolkit usage

The toolkit provides a real facility for editing single XML document.

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


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

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/tool.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/tool.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/tool.jar" WIDTH = "600" HEI
GHT = "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.

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. So if you wish to use actions with a tabbed pane system, you will have to reset action for each tabbed pane change.

From your the ActionModel you can :
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 is will be handled in real time.

b. Usage

1. Replacing existing 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 notifyAction() {
            editor.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);
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.

c. Default actions

Here available actions :

Name
Role
New
Build a new XML document. This action uses the XMLTemplate class for building a new page.
Load
Load an XML document
SaveAs
Save an XML document
Copy
Copy a text
Cut
Cut a text
Paste
Paste a text
Undo
Undo the last action but this is a new document action
Redo
Redo the last action but to undo action has been called
Refresh
Parse the current document and show any error in red
Search
Parse the current document and show a tree for easily navigating
Split
Split the current editor in two ones
Format
Ident the current XML text.

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. 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 or loaded. The DefaultDTD is used is no DTD is found in the current document
  2. By using a static document descriptor. This descriptor is not available directly. User have to call the addTagDescriptor method on the SyntaxHelper.

Usage sample :

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 use it :

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

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 parsing is made while saving or loading. However you can force it by calling the searchAndParseDTD on the XMLContainer.

IV. LookAndFeel

JXMLPad has a lookAndFeel plug-in system for :

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

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 :

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

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

V. 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.MozillaLook
tree
Show the real time tree
true
location
Localize the current cursor in the tree
true
fontname
Font name
Dialog
fontsize
Font size
12

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

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