Creating Dialogs at Runtime

From Apache OpenOffice Wiki
Jump to: navigation, search



When using Apache OpenOffice Basic, the dialog editor is a tool for designing dialogs. Refer to OpenOffice Basic IDE for additional information. Since OpenOffice.org 2.0.0, dialogs that have been built with the dialog editor can be loaded by a macro written in any of the supported scripting framework languages (BeanShell, JavaScript, Java, Apache OpenOffice Basic) by using the com.sun.star.awt.XDialogProvider API. See section Using the Scripting Framework for more details.

In addition, it is also possible to create dialogs at runtime in a similar way as Java Swing components are created. Also, the event listeners are registered at runtime at the appropriate controls.

An example dialog

In the Java example described in this section, a simple modal dialog is created at runtime containing a command button and label field. Each time the user clicks on the button, the label field is updated and the total number of button clicks is displayed.

The dialog is implemented as a UNO component in Java that is instantiated with the service name com.sun.star.examples.SampleDialog. For details about writing a Java component and the implementation of the UNO core interfaces, refer to Storing the Service Manager for Further Use. The method that creates and executes the dialog is shown below.

  /** method for creating a dialog at runtime
   */
  private void createDialog() throws com.sun.star.uno.Exception {
      // get the service manager from the component context
      XMultiComponentFactory xMultiComponentFactory = _xComponentContext.getServiceManager();
      // create the dialog model and set the properties
      Object dialogModel = xMultiComponentFactory.createInstanceWithContext(
          "com.sun.star.awt.UnoControlDialogModel", _xComponentContext);
      XPropertySet xPSetDialog = (XPropertySet)UnoRuntime.queryInterface(
          XPropertySet.class, dialogModel); 
      xPSetDialog.setPropertyValue("PositionX", new Integer(100));
      xPSetDialog.setPropertyValue("PositionY", new Integer(100));
      xPSetDialog.setPropertyValue("Width", new Integer(150));
      xPSetDialog.setPropertyValue("Height", new Integer(100));
      xPSetDialog.setPropertyValue("Title", new String("Runtime Dialog Demo"));
      // get the service manager from the dialog model
      XMultiServiceFactory xMultiServiceFactory = (XMultiServiceFactory)UnoRuntime.queryInterface(
          XMultiServiceFactory.class, dialogModel);
      // create the button model and set the properties
      Object buttonModel = xMultiServiceFactory.createInstance(
          "com.sun.star.awt.UnoControlButtonModel" );
      XPropertySet xPSetButton = (XPropertySet)UnoRuntime.queryInterface(
          XPropertySet.class, buttonModel);
      xPSetButton.setPropertyValue("PositionX", new Integer(50));
      xPSetButton.setPropertyValue("PositionY", new Integer(30));
      xPSetButton.setPropertyValue("Width", new Integer(50));
      xPSetButton.setPropertyValue("Height", new Integer(14));
      xPSetButton.setPropertyValue("Name", _buttonName);
      xPSetButton.setPropertyValue("TabIndex", new Short((short)0)); 
      xPSetButton.setPropertyValue("Label", new String("Click Me"));
      // create the label model and set the properties
      Object labelModel = xMultiServiceFactory.createInstance(
          "com.sun.star.awt.UnoControlFixedTextModel" );
      XPropertySet xPSetLabel = ( XPropertySet )UnoRuntime.queryInterface(
          XPropertySet.class, labelModel );
      xPSetLabel.setPropertyValue("PositionX", new Integer(40));
      xPSetLabel.setPropertyValue("PositionY", new Integer(60));
      xPSetLabel.setPropertyValue("Width", new Integer(100));
      xPSetLabel.setPropertyValue("Height", new Integer(14));
      xPSetLabel.setPropertyValue("Name", _labelName);
      xPSetLabel.setPropertyValue("TabIndex", new Short((short)1)); 
      xPSetLabel.setPropertyValue("Label", _labelPrefix);
      // insert the control models into the dialog model
      XNameContainer xNameCont = (XNameContainer)UnoRuntime.queryInterface(
          XNameContainer.class, dialogModel);
      xNameCont.insertByName(_buttonName, buttonModel);
      xNameCont.insertByName(_labelName, labelModel);
      // create the dialog control and set the model
      Object dialog = xMultiComponentFactory.createInstanceWithContext(
          "com.sun.star.awt.UnoControlDialog", _xComponentContext);
      XControl xControl = (XControl)UnoRuntime.queryInterface(
          XControl.class, dialog );
      XControlModel xControlModel = (XControlModel)UnoRuntime.queryInterface(
          XControlModel.class, dialogModel); 
      xControl.setModel(xControlModel);
      // add an action listener to the button control
      XControlContainer xControlCont = (XControlContainer)UnoRuntime.queryInterface(
          XControlContainer.class, dialog); 
      Object objectButton = xControlCont.getControl("Button1");
      XButton xButton = (XButton)UnoRuntime.queryInterface(XButton.class, objectButton);
      xButton.addActionListener(new ActionListenerImpl(xControlCont));
      // create a peer
      Object toolkit = xMultiComponentFactory.createInstanceWithContext(
          "com.sun.star.awt.Toolkit", _xComponentContext); 
      XToolkit xToolkit = (XToolkit)UnoRuntime.queryInterface(XToolkit.class, toolkit);
      XWindow xWindow = (XWindow)UnoRuntime.queryInterface(XWindow.class, xControl);
      xWindow.setVisible(false); 
      xControl.createPeer(xToolkit, null);
      // execute the dialog
      XDialog xDialog = (XDialog)UnoRuntime.queryInterface(XDialog.class, dialog);
      xDialog.execute();
      // dispose the dialog
      XComponent xComponent = (XComponent)UnoRuntime.queryInterface(XComponent.class, dialog);
      xComponent.dispose();
  }

First, a dialog model is created by prompting the ServiceManager for the com.sun.star.awt.UnoControlDialogModel service. Then, the position, size and title of the dialog are set using the com.sun.star.beans.XPropertySet interface. In performance critical applications, the use of the com.sun.star.beans.XMultiPropertySet interface is recommended. At this point, the dialog model describes an empty dialog, which does not contain any control models.

All control models in a dialog container have the common properties "PositionX", "PositionY", "Width", "Height", "Name", "TabIndex", "Step" and "Tag". These properties are optional and only added if the control model is created by a special object factory, namely the dialog model. Therefore, a dialog model also supports the com.sun.star.lang.XMultiServiceFactory interface. If the control model is created by the ServiceManager, these common properties are missing.

Documentation note.png Note that control models have the common properties "PositionX", "PositionY", "Width", "Height", "Name", "TabIndex", "Step" and "Tag" only if they were created by the dialog model that they belong to.

After the control models for the command button and label field are created, their position, size, name, tab index and label are set. Then, the control models are inserted into the dialog model using the com.sun.star.container.XNameContainer interface. The model of the dialog has been fully described.

To display the dialog on the screen, a dialog control com.sun.star.awt.UnoControlDialog is created and the corresponding model is set. An action listener is added to the button control, because the label field is updated whenever the user clicks on the command button. The listener is explained below. Before the dialog is shown, a window or a peer is created on the screen. Finally, the dialog is displayed on the screen using the execute method of the com.sun.star.awt.XDialog interface.

The implementation of the action listener is shown in the following example.

  /** action listener
   */
  public class ActionListenerImpl implements com.sun.star.awt.XActionListener {
      private int _nCounts = 0;
      private XControlContainer _xControlCont;
 
      public ActionListenerImpl(XControlContainer xControlCont) {
          _xControlCont = xControlCont;
      }
 
      // XEventListener
      public void disposing(EventObject eventObject) {
          _xControlCont = null;
      }
 
      // XActionListener
      public void actionPerformed(ActionEvent actionEvent) {
          // increase click counter
          _nCounts++;
 
          // set label text
          Object label = _xControlCont.getControl("Label1");
          XFixedText xLabel = (XFixedText)UnoRuntime.queryInterface(XFixedText.class, label); 
          xLabel.setText(_labelPrefix + _nCounts);
      } 
  }

The action listener is fired each time the user clicks on the command button. In the actionPerformed method of the com.sun.star.awt.XActionListener interface, an internal counter for the number of button clicks is increased. Then, this number is updated in the label field. In addition, the disposing method of the parent interface com.sun.star.lang.XEventListener is implemented.

Our sample component executes the dialog from within the office by implementing the trigger method of the com.sun.star.task.XJobExecutor interface:

  public void trigger(String sEvent) {
      if (sEvent.equals("execute")) {
          try {
              createDialog();
          }
          catch (Exception e) {
              throw new com.sun.star.lang.WrappedTargetRuntimeException(e.getMessage(), this, e);
          }
      }
  }

A simple Apache OpenOffice Basic macro that instantiates the service of our sample component and executes the dialog is shown below.

  Sub Main
      Dim oJobExecutor
      oJobExecutor = CreateUnoService("com.sun.star.examples.SampleDialog")
      oJobExecutor.trigger("execute")
  End Sub

In future versions of Apache OpenOffice, a method for executing dialogs created at runtime will be provided.

Content on this page is licensed under the Public Documentation License (PDL).
Personal tools
In other languages