Client code wanting to test whether a command can be executed given current DocumentView
context will just invoke method prepare
:
if (cmd.prepare(docView, param, x, y)) { // Do something, for example enable a button or a menu item. }
Client code wanting to actually execute a command will invoke the prepare
and execute
methods as follows:
if (cmd.prepare(docView, param, x, y)) {
cmd.execute(docView, param, x, y);
}
You can safely assume that method |
Therefore these methods may be informally described as follows:
prepare
Examines the context of the invocation: the node clicked upon (if arguments x
, y
have been specified), implicitly or explicitly selected nodes, the contents of the clipboard, etc.
If the command cannot be executed in this context, this method returns false
.
If the command can be executed in this context, this method returns true
. In such case, most commands update their internal state in order to facilitate the job of possibly following method execute
.
Method prepare
may be called quite often. For example, each time the selection implicitly or explicitly changes in current DocumentView
, the prepare
methods of the commands bound to XXE menu items and toolbar buttons are invoked. That's dozens of invocations at a time.Therefore,
Method prepare
must be as quick as possible,
Method prepare
may not report any information of any kind (even an error; silently return false
in such case) and may not log any information of any kind.
execute
Really does the job. Assumes that method prepare
has just returned true
.
Method execute
may be interactive. It may display dialog boxes prompting the user for some information. It may report error using alert dialog boxes, for example Alert.showError
. It may display status message using DocumentView.showStatus
.
Method execute
returns a CommandResult
. In its simplest form, a CommandResult
is just the status of the command execution:
CommandResult.STOPPED
Equivalent to new CommandResult(Status.STOPPED, null, null)
. The execution has been stopped because the command needs to display a dialog box and the computer on which the command runs has no display. Not useful unless you intend to run your command in XMLmind XML Editor Web Edition. More information below.
CommandResult.CANCELED
Equivalent to new CommandResult(Status.CANCELED, null, null)
. The command execution has been canceled by the user.
CommandResult.FAILED
Equivalent to new CommandResult(Status.FAILED, null, null)
. The command execution has failed.
CommandResult.DONE
Equivalent to new CommandResult(Status.DONE, null, null)
. The command execution has succeeded and the command did not return any meaningful value as its result.
Convenience method CommandResult.done(Object value)
may be be used to specify the result —an object of any kind, this depends entirely on the command— of a successful execution.
Is it execute or doExecute ? | |
---|---|
Method A third-party developer must always implement abstract method |
Methods prepare
, execute
(and doExecute
) have exactly the same parameters:
DocumentView docView
The DocumentView
on which the command is acting.
String parameter
This string parametrizes the behavior of the command. Each command has its own syntax for its parameter string. Commands which cannot be parametrized must be passed null
(null
may be also accepted by some commands which can be parametrized). See Chapter 6, Commands written in the Java™ programming language in XMLmind XML Editor - Commands for a complete description of available commands and their parameters.
int x, y
Some commands are designed to be bound to a mouse input. These arguments are the coordinates, in the DocumentView
coordinate system, of mouse input which triggered the command. For the other type of commands, designed to be bound to a keyboard input or to be invoked from a menu, these coordinates are set to -1
.
Let's use a very simple command, InsertCharByCodeCmd
, to illustrate all this. Sample command InsertCharByCodeCmd
inserts a character specified using its Unicode code point at caret location.
Excerpts from InsertCharByCodeCmd.java
:
public class InsertCharByCodeCmd extends CommandBase { private int code; public InsertCharByCodeCmd() { super(/*repeatable*/ true, /*recordable*/ true); } public boolean prepare(DocumentView docView, String parameter, int x, int y) { if (!docView.canInsertString()) { return false; } code = 0; if (parameter != null) { code = parseUnicode(parameter); if (code <= 0) { return false; } } return true; }
Instance variable
| ||||
More about this constructor in next section. | ||||
Specified parameter cannot be parsed as a Unicode code point. Notice that no error is reported to the user. The method simply returns |
public CommandResult doExecute(DocumentView docView, String parameter, int x, int y) { String title = "INSERT CHARACTER BY CODE"; if (code <= 0) { Component dialogParent = docView.getDialogParent(); if (dialogParent == null) { return CommandResult.STOPPED; } PromptDialog prompt = new PromptDialog(dialogParent, 20, /*browseButton*/ false, /*helpButton*/ false); String value = prompt.getValue(title, "Unicode character" + " (example \"U+2022\" for \"BULLET\"):", /*value*/ "", /*baseURL*/ null, /*allowAnyString*/ true); if (value == null || (value = value.trim()).length() == 0) { //docView.showStatus("Command canceled by user."); return CommandResult.CANCELED; } code = parseUnicode(value); if (code <= 0 || !XMLText.isXMLChar((char) code)) { Alert.showError(dialogParent, "Cannot parse \"" + value + "\" as an XML character."); return CommandResult.FAILED; } } docView.insertString(Character.toString((char) code), docView.getOverwriteMode()); return CommandResult.success(null, "U+" + Integer.toString((char) code, 16), title); }
This test is optional. The parent component of a dialog box is obtained using | |
Which character is to be inserted is not specified by | |
User clicked button Though not useful in such case, | |
The user has typed a string which cannot be parsed as a usable character, so stop the execution there by returning | |
Insert specified character at caret location using | |
This command could also have returned |
[3] xxeserver is designed to run on computers having no display (xxeserver is started with -Djava.awt.headless=true
) therefore docView.getDialogParent()
returns null
.