| Raben Systems Inc. | |
| Software Development Services |
| Home | About Us | Articles | Downloads | Solar maps | Space weather graphs | Wireless |
An XSLT Editor Tool - Part 3 - Undo, redo, cut, and paste
May 20, 2002 -- Part 3, Undo, redo, cut and paste. This article describes the code to add undo, redo, cut, and paste to the editor tool. (If you have not already done so, you may wish to read Part 1 - Basic GUI, Opening and Displaying XML Files) and Part 2 XSLT Transformations. Fortunately, Sun Microsystems has made very easy to add these basic edit operations to a JEditPane. Since there are separate edit windows for XML and XSLT, the application needs separate undo/redo for each. This complicates the solution, but only slightly. To provide "undo" capability, an "undoable edit listener" is added to the document.
xmlEditorPane.getDocument().addUndoableEditListener(new XmlUndoableEditListener());
Whenever the user modifies text in the XML Editor pane, the UndoableEditListeners only method, "undoableEditHappenned" is called. The edit that occurred is sent to an "UndoManager" object "xmlUndo". To create the undo manager, we need only instantiate the class "UndoManager".
/**
* Undo edit listener for XML Editor pane
*/
class XmlUndoableEditListener implements UndoableEditListener {
public void undoableEditHappened(UndoableEditEvent e) {
//Remember the edit and update the menus
xmlUndo.addEdit(e.getEdit());
xmlUndoAction.updateUndoState();
xmlRedoAction.updateRedoState();
}
}
The "xmlUndoAction" object above is an extension of an AbstractAction. When the action event occurs, the UndoManager's undo method is called.
/**
* Undo actions for XML Editor pane
*/
class XmlUndoAction extends AbstractAction {
public XmlUndoAction() {
super("Undo");
setEnabled(false);
}
public void actionPerformed(ActionEvent e) {
try {
xmlUndo.undo();
} catch (CannotUndoException ex) {
log("Unable to undo: " + ex);
xsltEditor.getToolkit().beep();
}
updateUndoState();
xmlRedoAction.updateRedoState();
}
protected void updateUndoState() {
if (xmlUndo.canUndo()) {
setEnabled(true);
putValue(Action.NAME, xmlUndo.getUndoPresentationName());
} else {
setEnabled(false);
putValue(Action.NAME, "Undo");
}
}
}
The code for the XmlRedo action is nearly identical
/**
* Redo actions for XML Editor pane
*/
class XmlRedoAction extends AbstractAction {
public XmlRedoAction() {
super("Redo");
setEnabled(false);
}
public void actionPerformed(ActionEvent e) {
try {
xmlUndo.redo();
} catch (CannotRedoException ex) {
log("Unable to redo: " + ex);
xsltEditor.getToolkit().beep();
//ex.printStackTrace();
}
updateRedoState();
xmlUndoAction.updateUndoState();
}
protected void updateRedoState() {
if (xmlUndo.canRedo()) {
setEnabled(true);
putValue(Action.NAME, xmlUndo.getRedoPresentationName());
} else {
setEnabled(false);
putValue(Action.NAME, "Redo");
}
}
}
Providing cut and paste capability is also quite easy. First a "edit" menu is created on the tool bar, and an action is associated with the menu item for each. When the user selects "cut" from the menu, the "cutMenuItemActionPerformed" method is called. The action determines which editor pane is currently selected, gets the selected text and sets the contents in the system clipboard. The editor pane's "cut" method is then called to remove the text.
/**
* Determine edit pane being used and cut text from the pane
* @param evt ActionEvent
*/
private void cutMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
JEditorPane editorPane=getSelectedEditorPane();
String selection=editorPane.getSelectedText();
StringSelection data = new StringSelection(selection);
clipboard.setContents(data, data);
editorPane.cut();
}
When the user selects "paste" from the menu, the "pasteMenuItemActionPerformed" method is called. The action determines which editor pane is currently selected, gets the contents of the clipboards and the calls the editor pane "replaceSelection" method to paste it in the edit pane.
private void pasteMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
Transferable clipData = clipboard.getContents(clipboard);
String selection="";
JEditorPane editorPane=getSelectedEditorPane();
if (clipData != null) {
try {
selection = (String)(clipData.getTransferData(DataFlavor.stringFlavor));
editorPane.replaceSelection(selection);
} catch (UnsupportedFlavorException ee) {
log("Unsupported flavor: " + ee);
} catch (IOException ee) {
log("Unable to get data: " + ee);
}
}
}
The "getSelectedEditorPane" method is trivial. It calls the tabbedPane "getSelectedIndex" method and then returns the appropriate editor pane.
private JEditorPane getSelectedEditorPane() {
JEditorPane editorPane=outputEditorPane;
switch(tabbedPane.getSelectedIndex()) {
case 0:
editorPane=xmlEditorPane;
break;
case 1:
editorPane=xsltEditorPane;
break;
case 2:
editorPane=resultEditorPane;
break;
case 3:
editorPane=outputEditorPane;
break;
}
return editorPane;
}
This series of articles has provided a brief tutorial on how to develop a simple XSLT and XML editor tool, complete with cut, paste, undo, and redo capabilities. The JavaDoc and source code cross reference are available. Source code for the tool is available for download (32 kbytes). After downloading the file, unzip it in a local directory. Then change your directory to the "local_directory/xslteditor-1.1-src". Assuming that ant is installed on your system, you may build it by executing "ant all". Ant will compile the distribution and create a executable jar file in the "xslteditor-1.1-src/dist" directory.
Article Index
Back to Examples
| ©2003 Raben Systems, Inc. All rights reserved. |
Home • About
Us • Accessibility •
Articles • Downloads •
Legal |