Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Command Framework

The command framework in the ReportDesigner is used to create menubars, toolbars and popup menus. The design of the framework simplifies the separation of model, view and control.

The main advantage lies in the updating of the presentations (actual menubar, toolbar) depending on the context. The command framework is responsible to detect whenever the underlying model, selection or focused element changes and makes the commands update its presentations. Commands don't have to register listeners in the model nor must commands know the exact structure of the application their working on. Only the data is important to a command. A command which moves the selected ReportElement 10 pixels up can simply ask for the selected element and call setPosition on this element. The element  can be selected in the structure tree or the main report panel or somewhere else, it does not matter to the command. The command does not even have to know that a structure tree is existing in the application.

Main classes involved when using the framework

org.pentaho.reportdesigner.lib.client.commands.Command

Interface implemented by all commands used to create a toolbarbutton or menu item. Implementations should be stateless. The command class implements the controller part of an action. One command can appear multiple times on the user interface and should therefore be stateless.
Samples of commands: OpenReportCommand, SaveReportCommand, ExitCommand

org.pentaho.reportdesigner.lib.client.commands.Presentation 

The presentation is the view of a command. It holds localized text, descriptions, icons, accelerator. Multiple presentations of a command can exist at the same time. e.g one presentation in the menubar, one in the toolbar and one temporarily in a popup menu. The command is responsible to update the presentation whenever the update method is called. A command usually disables the presentation when the required data is not available. The command can also change the text/icon/visibility of the presentation. e.g The undo command might change the text to contain a description of the operation to undo ("Undo change background").

org.pentaho.reportdesigner.lib.client.commands.CommandGroup

A CommandGroup can contain a set of commands belonging together.
Sample of a command group: Align Left/Center/Right etc. form a group. The group itself can be specified to be of type popup or normal to change the appearance type in the menubar or toolbar.

org.pentaho.reportdesigner.lib.client.commands.DataContext

Interface used by commands to request data of the current context. The context is usually focus dependent and changes whenever the user selects another component/element or the reporting model changes by an automated action from a background thread.
The datacontext is determined by the command framework by hierarchically walking the component tree from the deepest focused component upwards to the frame. The first encountered DataProvider is used to return the datacontext.

org.pentaho.reportdesigner.lib.client.commands.CommandManager

Central class to register command groups using a key. This class is used to create a menubar, toolbar or popup menu from the previously defined key.
e.g a command group containing all commands destined for the toolbar can be registerd using the key "Toolbar" (the key is completely user defined and has no special meaning).

Howto create a command from scratch 

Step 1: Create the command class (controller)

Code Block

public class MoveUpCommand extends AbstractCommand
{
    public SampleMoveUpCommand()
    {
        super("MoveUpCommand");
        getTemplatePresentation().setText("Move 10 pixels up");
    }


    public void update(@NotNull CommandEvent event)
    {
        ReportElement[] selectedElements = (ReportElement[]) event.getDataContext().getData(CommandKeys.KEY_SELECTED_ELEMENTS_ARRAY);
        event.getPresentation().setEnabled(selectedElements != null && selectedElements.length > 0);//only enable when something is selected
    }


    public void execute(@NotNull CommandEvent event)
    {
        ReportDialog reportDialog = (ReportDialog) event.getPresentation().getCommandApplicationRoot();
        reportDialog.getUndo().startTransaction(UndoConstants.MOVE_UP);
        ReportElement[] reportElements = (ReportElement[]) event.getDataContext().getData(CommandKeys.KEY_SELECTED_ELEMENTS_ARRAY);
        if (reportElements != null)
        {
            for (ReportElement reportElement : reportElements)
            {
                double x = reportElement.getPosition().x;
                double y = reportElement.getPosition().y - 10;
                reportElement.setPosition(new Point2D.Double(x, y));
            }
        }
        reportDialog.getUndo().endTransaction();
    }
}

The update method is automatically invoked whenever the command framework likes to (don't assume anything). The CommandEvent contains the presentation that should be updated. The update method is usually invoked for every presentation (e.g toolbar and menubar) of a command.

...

Step 2: Register the command in a group. 

Code Block

CommandManager.addCommandToGroup(reportDialog, "Toolbar", new MoveUpCommand(), CommandConstraint.LAST);

...

Step 3: Creating a toolbar and adding the JToolbar to the UI.

Code Block

commandToolBar = CommandManager.createCommandToolBar(this, "Toolbar");
getContentPane().add(commandToolBar.getToolBar(), BorderLayout.NORTH);