# JXMLPad

Version 1.9.4
http://www.japisoft.com
Tutorial 1: Creating a JSP editor

## Features :

- JDK 1.2 and later version compatible
- Java bean usage
- Syntax coloration (tag, string, entities...)
- Syntax helper
- Look-and-feel plugIn
- Customizable action toolbar
- Customizable coloration for tags, attributes,namespaces
- Syntax correction
- Template for fast creation
- Easy to integrate in your application
- Several standard action for XML usage (parsing, search, comment...)
- Standard Swing EditorKit
- Real time tree text synchronization and location
- Auto tag closing
- XML integrity for avoiding invalid XML document
- Customizable with a property file
- Very rich API
- Sample for JSP/XML editing, applet and standalone usage

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 :

- Replace existing action by your action
- Enable/Disable action
- Retreive an action by its name
- List available action
- Run an action by its name

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 :

- Element completion taking into account user location for selecting node. This mode will include required attributes.
- Entity completion
- System completion like CDATA or comment. This completion is enabled by inserting "<!".

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