LibreOffice Developer's Guide: Chapter 19 - Graphical User Interfaces

From The Document Foundation Wiki
Jump to navigation Jump to search

The <idlmodule>com.sun.star.awt</idlmodule> API-module is used to access and design user interface features. The concepts that this module are based on are similar to java.awt. This module provides services and interfaces to create and handle the large set of GUI elements that are demanded by today's modern components. This chapter is directed to extension developers who want to add functionality to their LibreOffice application and want to create a consistent user interface.

Implementation Details

You can use the UNO module Abstract Window Toolkit (UNO-AWT) to create a graphical user interface. The concept of UNO-AWT is based on Java/AWT. Java provides the AWT and Swing user interface design packages within its Java Foundation Classes class library. The implementation of java.awt components is based on the implementation of the peer components of the operating system. This is known as a "heavyweight" implementation. <idlmodule>com.sun.star.awt</idlmodule> components are lightweight controls because their implementation is based solely on LibreOffice. This gives you platform independence. The functionality of heavyweight controls may only be as high as the lowest common denominator of all involved operating systems, however, LibreOffice UI components are meant to emulate the design of the corresponding components of the operating system. The layer responsible for this is called VCL or Visual Class Library. The layer on top of the VCL is the Toolkit layer. This layer maps all interfaces of <idlmodule>com.sun.star.awt</idlmodule> to VCL.

Basic Concepts

The basic concepts that are used in <idlmodule>com.sun.star.awt</idlmodule> are described in previous chapters:

  • Event Model describes how to use event listeners at controls. With Event-Listeners at controls you can determine how a window reacts to mouse or keyboard driven events.
  • Exceptions explains how to handle errors as Exceptions.
  • Introduction describes factories.
  • Data Types describes the basic UNO types, and provides information about how to convert these types to and from various target languages.
  • LibreOffice Basic provides information for developers who want to implement Basic macros.
  • Accessing Dialogs explains how dialogs created with the dialog engine can be embedded within LibreOffice extensions.

Exception Handling

In theory, robust exception handling reacts to all unpredictable situations. In practice, many of these situations can be avoided by preventive runtime behavior or by making sure that the methods defined to raise exceptions are only used in a defined context. In these cases empty exception handling as done in the example code is justifiable.

Dialogs and Controls

The <idlmodule>com.sun.star.awt</idlmodule> module provides a set of services specifying UNO components that can be used within dialogs. The controls as well as the dialog itself, follow the Model-View-Controller (MVC) paradigm, which separates the component into three logical units, the model, view, and controller. The model represents the data and the low-level behavior of the component and has no specific knowledge of its controllers or its views. In practice this separation is not always strictly followed. The UNO control models can contain information about the visual display of the controls.

The view manages the visual display of the state represented by the model. The controller manages the user interaction with the model. Toolkit controls combine the view and the controller into one logical unit that forms the user interface for the component. For example, the text field model is implemented by the <idl>com.sun.star.awt.UnoControlEditModel</idl> service that extends the <idl>com.sun.star.awt.UnoControlModel</idl> service. All aspects of the model are described as a set of properties which are accessible through the <idl>com.sun.star.beans.XPropertySet</idl> interface. The view is responsible for the display of the text field and its content.

The controller handles the user input provided through the keyboard and mouse. If the user changes the text in a text field, the controller updates the corresponding model property. The controller also updates the view. For example, when the user selects some text in a text field and presses the delete key on the keyboard, the marked text in the text field is deleted.

A more detailed description of the MVC paradigm can be found in The Model-View Paradigm.

The base for all the Toolkit controls is the <idl>com.sun.star.awt.UnoControl</idl> service that exports the following interfaces:

  • The <idl>com.sun.star.awt.XControl</idl> interface specifies control basics. For example, it gives access to the model, view and context of a control.
  • The interfaces <idl>com.sun.star.awt.XWindow</idl>, <idl>com.sun.star.awt.XWindow2</idl>, <idl>com.sun.star.awt.XWindowPeer</idl> specify operations for a window component. They are all based on an equal footing and are a available on arbitrary UNO-objects representing windows.
  • The <idl>com.sun.star.awt.XView</idl> interface provides methods for attaching an output device and drawing an object.

Dialog Creation

To create a dialog you can design the dialog within the dialog engine (as explained in LibreOffice Basic) and add it to an extension project (as described in Accessing Dialogs). A programmatic approach to create a dialog is illustrated in the following process sequence:

Instantiation of a Dialog

The first step to create a dialog is to instantiate the dialog and its corresponding model . As can be seen in the following code example, the dialog as well as its model are created by the global MultiComponentFactory. The model is assigned to the dialog using setModel(). The dialog model is a <idl>com.sun.star.container.XNameContainer</idl> that keeps all control models and accesses them by their name. Similarly the dialog implements the interface <idl>com.sun.star.awt.XControlContainer</idl> that accesses the controls via the method getControl(). In a later step, each control model must be added to the Name-Container of the dialog model, which is why these object variables are defined with a public scope in the code example. Alternatively you can also retrieve the dialog model using the method getModel() at the dialog interface <idl>com.sun.star.awt.XControl</idl>.

public XNameContainer m_xDlgModelNameContainer = null;
public XControlContainer m_xDlgContainer = null;
...

private void createDialog(XMultiComponentFactory _xMCF) {
    try {
        Object oDialogModel = _xMCF.createInstanceWithContext("com.sun.star.awt.UnoControlDialogModel", m_xContext);

        // The XMultiServiceFactory of the dialogmodel is needed to instantiate the controls...
        m_xMSFDialogModel = (XMultiServiceFactory) UnoRuntime.queryInterface(XMultiServiceFactory.class, oDialogModel);

        // The named container is used to insert the created controls into...
        m_xDlgModelNameContainer = (XNameContainer) UnoRuntime.queryInterface(XNameContainer.class, oDialogModel);

        // create the dialog...
        Object oUnoDialog = _xMCF.createInstanceWithContext("com.sun.star.awt.UnoControlDialog", m_xContext);
        m_xDialogControl = (XControl) UnoRuntime.queryInterface(XControl.class, oUnoDialog);

        // The scope of the control container is public...
        m_xDlgContainer = (XControlContainer) UnoRuntime.queryInterface(XControlContainer.class, oUnoDialog);

        m_xTopWindow = (XTopWindow) UnoRuntime.queryInterface(XTopWindow.class, m_xDlgContainer);

        // link the dialog and its model...
        XControlModel xControlModel = (XControlModel) UnoRuntime.queryInterface(XControlModel.class, oDialogModel);
        m_xDialogControl.setModel(xControlModel);
    } catch (com.sun.star.uno.Exception exception) {
        exception.printStackTrace(System.out);
    }
}

Setting Dialog Properties

When the dialog has been instantiated as described in the coding example, the dialog is ready to be configured.

The dialog model supports the service <idl>com.sun.star.awt.UnoControlDialogModel</idl> that includes the service <idl>com.sun.star.awt.UnoControlModel</idl>, and this includes <idl>com.sun.star.awt.UnoControlDialogElement</idl>. This service specifies the following properties:

Properties of <idl>com.sun.star.awt.UnoControlDialogElement</idl>
<idlm>com.sun.star.awt.UnoControlDialogElement:Height</idlm> long. Attributes denoting the position and size of controls are also available at the control, but these properties should be set at the model because they use the Map AppFont unit. Map AppFont units are device and resolution independent. One Map AppFont unit is equal to one eighth of the average character (Systemfont) height and one quarter of the average character width. The dialog editor also uses Map AppFont units, and sets their values automatically.
<idlm>com.sun.star.awt.UnoControlDialogElement:PositionX</idlm>
<idlm>com.sun.star.awt.UnoControlDialogElement:PositionY</idlm>
<idlm>com.sun.star.awt.UnoControlDialogElement:Width</idlm>
<idlm>com.sun.star.awt.UnoControlDialogElement:Step</idlm> long. The Step property is described in detail in the next section.
<idlm>com.sun.star.awt.UnoControlDialogElement:Name</idlm> string. The Name property is required, because all dialogs and controls are referenced by their name. In the dialog editor this name is initially created from the object name and a number that makes the name unique, for example, "TextField1".
<idlm>com.sun.star.awt.UnoControlDialogElement:TabIndex</idlm> short. The TabIndex property determines the tabulator index of the control within the tabulator order of all controls of the dialog. The tabulator order denotes the order in which the controls are focused in the dialog when you press the Tab key. In a dialog that contains more than one control, the focus moves to the next control in the tabulator order when you press the Tab key. The default tab order is derived from the insertion order of the controls in the dialog. The index of the first element has the value 0.

The TabIndex must not be directly sequential to the predecessor control. If the program logic requires you to insert an uncertain number of controls between two controls during runtime, a number of tab indices can be kept free in between the two controls.

<idlm>com.sun.star.awt.UnoControlDialogElement:Tag</idlm> string. The Tag property can be used to store and evaluate additional information at a control. This information may then be used in the program source code.

A dialog model exports the interfaces <idl>com.sun.star.beans.XPropertySet</idl> and <idl>com.sun.star.beans.XMultiPropertySet</idl>. When you set multiple properties at the same time you should use <idl>com.sun.star.beans.XMultiPropertySet</idl> because then multiple properties can be set with a single API call. When you use <idl>com.sun.star.beans.XMultiPropertySet</idl> you must remember to pass the properties in alphabetical order (see the examples in the following chapters).

Warning.svg

Warning:
Note: Toolkit control models are generally configured by attributes that are defined in the service descriptions, whereas controls usually implement interfaces. This same principle applies to dialogs.


The following code snippet demonstrates the assignment of the most important dialog properties:

// Define the dialog at the model - keep in mind to pass the property names in alphabetical order!
String[] sPropertyNames = new String[] {"Height", "Moveable", "Name","PositionX","PositionY", "Step", "TabIndex","Title","Width"};

Object[] oObjectValues = new Object[] { new Integer(380), Boolean.TRUE, "MyTestDialog", new Integer(102),new Integer(41), new Integer(0), new Short((short) 0), "OpenOffice", new Integer(250)};
setPropertyValues( sPropertyNames, oObjectValues);

...

public void setPropertyValues(String[] PropertyNames, Object[] PropertyValues) {
    try {
        XMultiPropertySet xMultiPropertySet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, m_xDlgModelNameContainer);
        xMultiPropertySet.setPropertyValues(PropertyNames, PropertyValues);
    } catch (com.sun.star.uno.Exception ex) {
        ex.printStackTrace(System.out);
    }
}

Multi-Page Dialogs

A dialog may have several pages that can be traversed step-by-step. This feature is used in the LibreOffice wizards. The dialog-model property Step defines which page of the dialog is active. At runtime, the next page of a dialog is displayed by increasing the Step value by 1. The Step property of a control defines the page of the dialog that the control is visible on. For example, if a control has a Step value of 1, it is only visible on page 1 of the dialog. If the Step value of the dialog is increased from 1 to 2, then all controls with a Step value of 1 are removed and all controls with a Step value of 2 become visible. A special role has the Step value 0. If the control's Step is assigned to a value of 0, the control is displayed on all dialog pages. If the dialog's Step property is assigned to 0, all controls regardless of their Step value are displayed. The property Visible, specified in the service <idl>com.sun.star.awt.UnoControlModel</idl> determines if a control should appear on a certain step or not. However, the effective visibility of a control also depends on the value of the Step property. A control is visible only when the Visible property is set to true and when the value of the control Step property is equal to the dialog Step property.

Adding Controls to a Dialog

After the dialog and its model have been instantiated and configured, the dialog controls can be added as described in Programming Dialogs and Dialog Controls.

Displaying Dialogs

After you have inserted the controls, you can create a WindowPeer, a low level object that makes sure the window is displayed correctly, and the dialog can be executed. A dialog implements <idl>com.sun.star.awt.XWindow</idl>. To access the window toolkit implementation, a <idl>com.sun.star.awt.XWindowPeer</idl> must be created. The dialog control is shown by calling the execute() method of the <idl>com.sun.star.awt.XDialog</idl> interface. It can be closed by calling endExecute(), or by offering a Cancel or OK Button on the dialog Command Button. Dialogs such as this one are described as modal because they do not permit any other program action until they are closed. While the dialog is open, the program remains in the execute() call. The dispose() method at the end of the code frees the resources used by the dialog. It is important to note that dispose() - the method to free the memory - must be positioned directly after the execute() call and not behind endExecute();

public short executeDialog() throws com.sun.star.script.BasicErrorException{
    XWindow xWindow = (XWindow) UnoRuntime.queryInterface(XWindow.class, m_xDlgContainer);
    // set the dialog invisible until it is executed
    xWindow.setVisible(false);
    Object oToolkit = m_xMCF.createInstanceWithContext("com.sun.star.awt.Toolkit", m_xContext);
    XToolkit xToolkit = (XToolkit) UnoRuntime.queryInterface(XToolkit.class, oToolkit);
    XWindowPeer xWindowParentPeer = xToolkit.getDesktopWindow();
    m_xDialogControl.createPeer(xToolkit, xWindowParentPeer);
    m_xWindowPeer = m_xDialogControl.getPeer();
    XDialog xDialog = (XDialog) UnoRuntime.queryInterface(XDialog.class, m_xDialogControl);
    XComponent xDialogComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, m_xDialogControl);

    // the return value contains information about how the dialog has been closed...
    short nReturnValue = xDialog.execute();
    // free the resources...
    xDialogComponent.dispose();
    return nReturnValue;
}

The method createPeer() creates an internal or low level peer-object, that makes sure that the window is displayed correctly.

Dialog Handling

When a designed dialog has been executed either after it has been created via a dialog editor or programmatically, there usually is a demand to interact with the dialog, or query its state or the states of its contained controls during runtime. This topic will help you become familiar with how to handle UNO dialogs during runtime, and it will provide you with an overview of all of the supported dialog controls. It does not provide a complete description of all involved facets. It is meant to provide you with the information you need to solve individual problems on your own. Additional information can be found in the respective interface and service descriptions.

Tip.svg

Tip:
You will most probably want your extension to integrate into LibreOffice. The LibreOffice style guide under DialogSpecificationandGuidelines.odt defines the rules that user interface elements must follow in order to give the application a consistent look and feel.


Tip.svg

Tip:
A specification guide that defines the general behavior of LibreOffice assistance was Wizards_NewConcept.sxw.


Events

LibreOffice dialogs are based on an event-oriented programming model where you can assign event handlers to the control elements. An event handler runs a predefined procedure when a particular action occurs. Event handlers are always added directly to the control (not to the control models). All dialog controls implement the interface <idl>com.sun.star.awt.XControl</idl> which extends the interface <idl>com.sun.star.awt.XWindow</idl>. Listeners are added to a control with a specific add<ListenerName>Listener() method like addMouseListener( [in] XMouseListener xListener ). Listeners are removed with a specific remove<ListenerName>Listener() method like removeMouseListener( [in] XMouseListener xListener ).

The methods of all listener interfaces have a parameter of a type derived from <idl>com.sun.star.lang.EventObject</idl>, for example <idl>com.sun.star.awt.MouseEvent</idl>, <idl>com.sun.star.awt.FocusEvent</idl> etc. This event object always carries a property Source by which it is possible to query the control an event has been triggered at.

The following code example shows how to implement an XActionListener. You must remember to implement the disposing() method as dictated by <idl>com.sun.star.lang.XEventListener</idl>. disposing() is supposed to be triggered when a dispose() command at the control has been invoked.

public void actionPerformed(ActionEvent rEvent) {
    try {
        // get the control that has fired the event,
        XControl xControl = (XControl) UnoRuntime.queryInterface(XControl.class, rEvent.Source);
        XControlModel xControlModel = xControl.getModel();
        XPropertySet xPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xControlModel);
        String sName = (String) xPSet.getPropertyValue("Name");
        // just in case the listener has been added to several controls,
        // we make sure we refer to the right one
        if (sName.equals("CommandButton1")) {
            //...
        }
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
}

Mouse Listeners

Events that correspond to mouse actions are triggered by a <idl>com.sun.star.awt.XMouseListener</idl> that react to mouse movements over a control. Popular use-cases for a mouse listener are changing the mouse pointer when the mouse moves over the window or querying the click count of the event mousePressed([in] com.sun.star.awt.MouseEvent e) when you want to differentiate between a single-click and a double click. For this purpose all methods carry a parameter <idls>com.sun.star.awt.MenuEvent</idls>, a structure that contains amongst other things, the member ClickCount. Other members (PositionX and PositionY) are to query the mouse position during the event invocation and Buttons that refers to the pressed mouse buttons.

A MouseMotionListener that implements <idl>com.sun.star.awt.XMouseMotionListener</idl> can be used when a movement of the mouse pointer must be observed. The following example code shows a part of an implementation of a mouse motion listener that is executed when the mouse is entering a control. For further information about WindowPeers, see Displaying Dialogs.

public void mouseEntered(MouseEvent _mouseEvent) {
    try {
        // retrieve the control that the event has been invoked at...
        XControl xControl = (XControl) UnoRuntime.queryInterface(XControl.class, _mouseEvent.Source);
        Object tk = m_xMCF.createInstanceWithContext("com.sun.star.awt.Toolkit", m_xContext);
        XToolkit xToolkit = (XToolkit) UnoRuntime.queryInterface(XToolkit.class, tk);
        // create the peer of the control by passing the windowpeer of the parent
        // in this case the windowpeer of the control
        xControl.createPeer(xToolkit, m_xWindowPeer);
        // create a pointer object "in the open countryside" and set the type accordingly...
        Object oPointer = this.m_xMCF.createInstanceWithContext("com.sun.star.awt.Pointer", this.m_xContext);
        XPointer xPointer = (XPointer) UnoRuntime.queryInterface(XPointer.class, oPointer);
        xPointer.setType(com.sun.star.awt.SystemPointer.REFHAND);
        // finally set the created pointer at the windowpeer of the control
        xControl.getPeer().setPointer(xPointer);
    } catch (com.sun.star.uno.Exception ex) {
        throw new java.lang.RuntimeException("cannot happen...");
    }
}

Keyboard Listener

Keyboard events can be captured by a KeyListener that implements <idl>com.sun.star.awt.XKeyListener</idl>. This allows you to verify each keyboard stroke. This listener is very useful for edit controls. The interface dictates the implementation of the two methods keyPressed() and keyReleased().

public void keyReleased(KeyEvent keyEvent) {
    int i = keyEvent.KeyChar;
    int n = keyEvent.KeyCode;
    int m = keyEvent.KeyFunc;
}

Focus Listener

A focus listener implementing <idl>com.sun.star.awt.XFocusListener</idl> is notified when the focus is entering (focusGained()) or leaving (focusLost()) a control.

The FocusListener is usually used to verify the user input when the control loses the focus.

This example demonstrates how to use the focusEvent:

public void focusLost(FocusEvent _focusEvent) {
    short nFocusFlags = _focusEvent.FocusFlags;
    int nFocusChangeReason = nFocusFlags & FocusChangeReason.TAB;
    if (nFocusChangeReason == FocusChangeReason.TAB) {
        // get the window of the Window that has gained the Focus...
        // Note that the xWindow is just a representation of the controlwindow
        // but not of the control itself
        XWindow xWindow = (XWindow) UnoRuntime.queryInterface(XWindow.class, _focusEvent.NextFocus);
    }
}

Paint Listener

Paint Listeners implementing <idl>com.sun.star.awt.XPaintListener</idl> are used to repaint areas that have become invalid.

Control element-specific events

Control element-specific events are events that only occur in relation to certain control elements.

The When initiating event is implemented in some control-button models. It is particularly useful because it is sent by either a key-press or a mouse-down action. Thus, it provides a consistent interface for users who navigate by mouse or by keyboard. If the model implements the Repeat capability, When initiating is the event that is repeatedly sent.

Dialog Controls

Dialog controls follow the MVC paradigm Frame-Controller-Model Paradigm in LibreOffice. Many attributes are offered by the control model that you would normally expect to find in the control itself. Properties like Visible or Printable are examples of typical view attributes that are available in the model.

All control models within a UNO dialog support the service <idl>com.sun.star.awt.UnoControlModel</idl>, that includes <idl>com.sun.star.awt.UnoControlDialogElement</idl>, as described in Setting Dialog Properties. It exports the interfaces <idl>com.sun.star.beans.XPropertySet</idl> and <idl>com.sun.star.beans.XMultiPropertySet</idl>. When you set multiple properties at the same time you should use [IDL:com.sun.star.beans.XMultiPropertySet] because then multiple properties can be set with a single API call. When you use <idl>com.sun.star.beans.XMultiPropertySet</idl> make sure you pass the properties in alphabetical order. All relevant properties may be set directly in the control model. Some controls offer similar functionality, but by default you should always work in the control model.

The coding examples in the following sections concentrate on control models as the default.

Controls are required to:

  • Attach listeners.
  • Get Window or device dependent information.
  • Use the "convenience" functionality offered by list boxes.
  • Adjust the size according to the content. The interface <idl>com.sun.star.awt.XLayoutConstrains</idl> offers methods like getPreferredSize() that can be helpful when the size of the control is to be adjusted to its content. You must remember that the Unit of the returned size is according to the specification in <idl>com.sun.star.awt.Size</idl> in 1/100th mm. This size may be applied with setSize() at the control.

Common Properties

The common set of properties that are used by all controls are:

Common Properties of all control models
Enabled The Enabled property can be set to true or false to enable or disable a button during runtime.
HelpText Help text is displayed as a tip on the control when the mouse moves over the control.
HelpURL The HelpURL is the URL of a help document. When the control has the focus, you can press F1 to open the help document. This feature is not yet available for embedded custom help documents. See issue http://www.openoffice.org/issues/show_bug.cgi?id=20164 for more information.

Currently the only supported "Help URL scheme" follows the pattern "HID:<HELPID>".

Printable If Printable set to false, the control is not visible on printer outputs.
Tabstop The Tabstop property defines if a control can be reached with the TAB key.
Visible The property Visible defines whether a dialog control is shown on its assigned dialog-step or not. The effective Visibility of a control is thus derived from the values of both properties Step and Visible. For example if the Step property of the control model is not equal to the Step property of the dialog model (that denotes the actual visible dialog step) the control will not be visible. In contrast, the method setVisible( [in] boolean Visible ) at the interface <idl>com.sun.star.awt.XWindow</idl> can be applied to the control and will set the Visibility of the control regardless the value of the Step property.

Font-specific Properties

The following properties are available on all controls with descriptive texts such as text fields, command buttons, radio buttons and check boxes. They are in all respective service specifications of these controls (it is the model's service description). When you are working with font properties, https://www.openoffice.org/issues/show_bug.cgi?id=71482 must be considered.

Properties referring to Font Attributes
[FontDescriptor] The property FontDescriptor applies to the structure <idl>com.sun.star.awt.FontDescriptor</idl>, where all available characteristics of the font may be set.
[FontEmphasisMark] Determines the type and position of an emphasis mark in Asian texts. It can accept any of the values in <idls>com.sun.star.awt.FontEmphasisMark</idls>.
[FontRelief] The FontRelief property accepts three values: (com.sun.star.text.FontRelief.) NONE (default), EMBOSSED or ENGRAVED. The embossed relief makes the characters appear as if they are raised above the page. The engraved relief makes the characters appear as if they are pressed into the page.
[FontCharWidth]

([com.sun.star.awt.FontDescriptor.CharacterWidth])

float. Specifies the character width.
[FontCharset]

([com.sun.star.awt.FontDescriptor.CharSet])

short. Specifies the character set which is supported by the font. It can be any of the constants defined in <idl>com.sun.star.awt.CharSet</idl>.
[FontName]

([com.sun.star.awt.FontDescriptor.Name])

string. Specifies the exact name of the font.
[FontFamily]

([com.sun.star.awt.FontDescriptor.Family])

Specifies the family style of a font and can accept values from the constants group <idl>com.sun.star.awt.FontFamily</idl>. This defines the group of typefaces with similar characteristics. Recognized families are Roman, Swiss, Modern, Script, and Decorative. For example, "Arial", "Arial Bold", "Arial Bold Italic", "Arial Italic", Small Fonts, and MS Sans Serif are all part of the sans serif Swiss font family.
[FontHeight]

([com.sun.star.awt.FontDescriptor.Height])

short. Specifies the height of the font in the measure of the destination.
[FontWidth]

([com.sun.star.awt.FontDescriptor.Width])

short. Specifies the width of the font in the measure of the destination.
[FontKerning]

([com.sun.star.awt.FontDescriptor.Kerning])

boolean. Font kerning defines the process of adjusting letter spacing in a proportional font. The value of the property indicates if there is a kerning table available for the font. The kerning table contains the values that control the intercharacter spacing for the glyphs in a font.
[FontOrientation]

([com.sun.star.awt.FontDescriptor.Orientation])

short. Specifies the rotation of the font in degrees where 0 is the baseline.
[FontPitch]

([com.sun.star.awt.FontDescriptor.Pitch])

short. The font pitch defines whether the width of a character of a font is fixed (as in monospaced fonts) or variable. It may accept one of the values defined in the constants group <idl>com.sun.star.awt.FontPitch</idl> .
[FontSlant]

([com.sun.star.awt.FontDescriptor.Slant])

Specifies how slanted the characters should be. It can be any value of the enumeration <idl>com.sun.star.awt.FontSlant</idl>, denoting (reverse) italic or (reverse) oblique or none slants.
[FontStrikeout]

([com.sun.star.awt.FontDescriptor.Strikeout])

Specifies the strikeout style of the text as defined by the constants group <idl>com.sun.star.awt.FontStrikeout</idl>.
[FontStyleName]

([com.sun.star.awt.FontDescriptor.StyleName])

string. Indicates the individual style of a font. For example "Bold", "Bold Italic" and "Italic" are defined styles of the font "Arial".
[FontType]

([com.sun.star.awt.FontDescriptor.Type])

short. Specifies the technology of the font representation as defined by the constants group <idl>com.sun.star.awt.FontType</idl>. These constants either indicate if a font is a raster font.

A scalable font (or "vector font" or "outline font") is one defined as vector graphics, i.e. as a set of lines and curves to define the border of glyphs, as opposed to a bitmap font, which defines each glyph as an array of pixels.

A device font is a font that is only presentable on a special device like a printer. LibreOffice} may use device independent metrics to display these fonts.

[FontUnderline]

([com.sun.star.awt.FontDescriptor.Underline])

Specifies the underlining style of the text as defined by the constants group <idl>com.sun.star.awt.FontUnderline</idl>.
[FontWeight]

([com.sun.star.awt.FontDescriptor.Weight])

float. Specifies the thickness of the font lines as a percentage relative to the inherited font weight.
[FontWordLineMode]

([com.sun.star.awt.FontDescriptor.WordLineMode])

boolean. Specifies if only words get underlined. True means that only non-space characters get underlined, false means that the spacing also gets underlined. This property is only valid if the property <idlm>com.sun.star.awt.FontDescriptor:com.sun.star.awt.FontDescriptor.UnderLine</idlm> is not FontUnderline.NONE.

Font properties may either be set as single properties or as a whole by means of the font descriptor which is useful when you want to assign the same properties to multiple objects.

Other Common Properties

The following properties are used by most controls:

Properties
[BackgroundColor] long. Sets the background color of the control. Its value is an integer type representing an RGB value as described in <idls>com.sun.star.util.Color</idls>.
[TextColor] long. Refers to the color of the text. When no specific text color is applied, it returns void.
[TextLineColor] long. Refers to the underlining style color of the text. If Underlining is not applied it is void. See also Font-specific Properties
[BorderColor] long. Refers to the color of the border (see Border-property). When no specific text color is applied, it returns void. Not every border style may support coloring. For example, a border with 3D effect will usually ignore the BorderColor setting.
[Label] string. The actual text displayed in a control is set by the Labelproperty of the model. A shortcut key can be defined for any control with a label by adding a tilde (~) before the character that will be used as a shortcut. When the user presses the character key simultaneously with the ALT key, the control automatically gets the focus.
[MultiLine] boolean. By default, the label displays the text from the Labelproperty in a single line. If the text exceeds the width of the control, the text is truncated (but not the data of the text). This behavior is changed by setting the MultiLineproperty to true, so that the text is displayed on more than one line if needed.
[Align] short. Specifies the horizontal alignment of the text in the control.
[VerticalAlign] short. Specifies the vertical alignment of the text in the control. Available options are (com.sun.star.style.VerticalAlignment).TOP, BOTTOM and MIDDLE.
[Border] short. Many controls support this property which accepts three values from the enumeration <idl>com.sun.star.awt.VisualEffect</idl> that defines if no Border, a flat border or a 3D border is to be applied.

As LibreOffice emulates the look and feel of the operating system, changing some of these properties may not have any effect. There is no strict rule to be followed when property changes are ignored or not.

Property Propagation Between Model and Control

One particularity in the relationship of UNO controls and their models must be considered. Following the principles of the MVC paradigm all changes applied to the control model are directly propagated to the control and (its peer object). However, conversely not all changes applied to the control will notify the model. The general rule is that whenever an attribute of a control is modifiable by the user, a change of this attribute is also propagated to the model. The following table sums up all methods which invocation at UNO controls is propagated to the respective control model. The controls and interfaces are described in detail in the following sections.

Control Service Name in module com.sun.star.awt Interface in <idlmodule>com.sun.star.awt</idlmodule> Method Name Model Service in <idlmodule>com.sun.star.awt</idlmodule> Affected Property at the model
UnoControlCheckBox XCheckBox get]State UnoControlCheckBoxModel State
UnoControlRadioButton XRadioButton get]State UnoControlRadioButtonModel State
UnoControlScrollBar XScrollBar get]Value UnoControlScrollBarModel ScrollValue
UnoControlComboBox XComboBox get]Item[s], add/removeItem UnoControlComboBoxModel Text, StringItemList
UnoControlListBox XListBox get]Item[s], [add|remove]Item,

selectItem, selectItemPos()

UnoControlListBoxModel StringItemList*,

SelectedItems

UnoControlEdit XTextComponent get]Text; UnoControlEditModel Text
UnoControlCurrencyField XCurrencyField

XTextComponent

get]Value,

[set|get]Text

UnoControlCurrencyModel Value
UnoControlDateField XDateField

XTextComponent

get]Date,

[set|get]Text

UnoControlDateModel Date
UnoControlTimeField XTimeField

XTextComponent

get]Time,

[set|get]Text

UnoControlTimeModel Time
UnoControlNumericField XNumericField

XTextComponent

get]Value

[set|get]Text

UnoControlNumericFieldModel Value
UnoControlPatternField XPatternField

XTextComponent

get]String,

[set|get]Text

UnoControlPatternFieldModel Text

Common Workflow to add Controls

For any existing dialog controls there is a common workflow to follow to insert a control into a dialog:

  1. Instantiate the control model at the MultiServiceFactory of the dialog.
  2. Set the Properties at the control model (for performance reasons, use the interface <idl>com.sun.star.beans.XMultiPropertySet</idl>).
  3. Insert the control model at the control model container of the dialog model. In our coding examples we refer to this container by the public object variable m_xDlgModelNameContainer created in the code example of Instantiation of a Dialog
  4. Query the control from the dialog control container by referencing the name (that you have previously assigned to the control model). Note: According to the MVC paradigm there is no way to retrieve the control from the model.

The Example Listings

As is generally known, an example is worth a thousand words. This is especially true for UNO. Sourcecode written in UNO is very often self-explanatory and for this reason the following sections provide a large set of example listings. Some of them are ready-to-use, whereas the focus of other examples is on demonstrating concepts.

All coding examples that demonstrate how to insert controls into a dialog make use of the following method:

/** makes a String unique by appending a numerical suffix
* @param _xElementContainer the com.sun.star.container.XNameAccess container
* that the new Element is going to be inserted to
* @param _sElementName the StemName of the Element
*/
public static String createUniqueName(XNameAccess _xElementContainer, String _sElementName) {
    boolean bElementexists = true;
    int i = 1;
    String BaseName = _sElementName;
    while (bElementexists) {
        bElementexists = _xElementContainer.hasByName(_sElementName);
        if (bElementexists) {
            i += 1;
            _sElementName = BaseName + Integer.toString(i);
        }
    }
    return _sElementName;
}

As already explained, the dialog keeps the controls in a NamedContainer that implements <idl>com.sun.star.container.XNameAccess</idl>. It is absolutely necessary for the controls to have a unique name before they are added to the dialog to prevent a <idl>com.sun.star.container.ElementExistException</idl>. This method appends a suffix to the scheduled name of the control to make sure that the name is unique.

Label Field

A label field control supports the service <idl>com.sun.star.awt.UnoControlFixedText</idl> and the model <idl>com.sun.star.awt.UnoControlFixedTextModel</idl>.It displays descriptive texts that are not meant to be edited by the user, such as labels for list boxes and text fields. By default, the label field control is drawn without a border. The format of the text can be set by the properties as described in Font-specific Properties. Label controls can be used to assign shortcut keys for controls without labels that succeed the label field control. To assign a shortcut key to a control without a label such as a text field, the label field is used. The tilde (~) prefixes the corresponding character in the Labelproperty of the label field. A fixed text control cannot receive the focus, so the focus automatically moves to the next control in the tab order. It is important that the label field and the text field have consecutive tab indices.

The following example demonstrates how to create a UnoControlFixedText control. You can create all types of dialog controls in the same way as is shown in this example. This example assumes that a dialog has already been created as described in Instantiation of a Dialog. This example also shows how to add a mouse listener.

public XFixedText insertFixedText(XMouseListener _xMouseListener, int _nPosX, int _nPosY, int _nWidth, int _nStep, String _sLabel) {
    XFixedText xFixedText = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "Label");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oFTModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlFixedTextModel");
        XMultiPropertySet xFTModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oFTModel);
        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!

        xFTModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "PositionX", "PositionY", "Step", "Width"},
        new Object[] { new Integer(8), sName, new Integer(_nPosX), new Integer(_nPosY), new Integer(_nStep), new Integer(_nWidth)});
        // add the model to the NameContainer of the dialog model
        m_xDlgModelNameContainer.insertByName(sName, oFTModel);

        // The following property may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        XPropertySet xFTPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oFTModel);
        xFTPSet.setPropertyValue("Label", _sLabel);

        // reference the control by the Name
        XControl xFTControl = m_xDlgContainer.getControl(sName);
        xFixedText = (XFixedText) UnoRuntime.queryInterface(XFixedText.class, xFTControl);
        XWindow xWindow = (XWindow) UnoRuntime.queryInterface(XWindow.class, xFTControl);
        xWindow.addMouseListener(_xMouseListener);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xFixedText;
}

Command Button

The command button <idl>com.sun.star.awt.UnoControlButton</idl> allows the user to perform an action by clicking on it. Usually a command button displays a label that is set by the Label property of the control model that supports the service <idl>com.sun.star.awt.UnoControlButtonModel</idl>.

A command button supports the display of images as explained in Image Control.

Properties of <idl>com.sun.star.awt.UnoControlButtonModel</idl>
<idlm>com.sun.star.awt.UnoControlButtonModel:DefaultButton</idlm> boolean. The DefaultButton property specifies that the command button is the default button on the dialog. Pressing the ENTER key chooses the button even if another control has the focus.
<idlm>com.sun.star.awt.UnoControlButtonModel:ImagePosition</idlm> short. The position of an image may be set. This is useful because the ImagePosition property is defined as relative to the Label of the control. It accepts one of the values defined in the constants group <idlm>com.sun.star.awt.UnoControlButtonModel:ImagePosition</idlm>
<idlm>com.sun.star.awt.UnoControlButtonModel:ImageURL</idlm> string. The ImageURL property contains the path to a graphics file. The image can be shown on the command button.
<idlm>com.sun.star.awt.UnoControlButtonModel:Graphic</idlm> com.sun.star.
<idlm>com.sun.star.awt.UnoControlButtonModel:ImageAlign</idlm> short. All standard graphics formats are supported, such as .gif, .jpg, .tif, .wmf and .bmp. The ImageAlign property defines the alignment and accepts one of the values defined in <idl>com.sun.star.awt.ImageAlign</idl>. The image is not automatically scaled, and can be cut off.
<idlm>com.sun.star.awt.UnoControlButtonModel:PushButtonType</idlm> short. The default action of the command button is defined by the PushButtonType property. It accepts the values defined in the enumeration <idl>com.sun.star.awt.PushButtonType</idl>. An OK button returns 1 on execute(). The default action of a Cancel button is to close the dialog, and execute() will return 0.
<idlm>com.sun.star.awt.UnoControlButtonModel:Toggle</idlm> boolean. If this property is set to true, a single operation of the command button control (pressing space while it is focused, or clicking onto it) toggles it between a pressed and a not-pressed state.

The default for this property is false, which means the button behaves like a usual push button.

<idlm>com.sun.star.awt.UnoControlButtonModel:Repeat</idlm> boolean. If this property is set to true, a single operation on the command button control (pressing and holding space while it is focused, or pressing and holding the mouse button) sends repeated events (When Initiating). Mouse events are sent at intervals of RepeatDelay milliseconds. This is similar to the functionality of the arrows on a scroll bar.
<idlm>com.sun.star.awt.UnoControlButtonModel:RepeatDelay</idlm> long. Delay in milliseconds between repeated mouse events (see Repeat, above). Keyboard repeat timing is controlled elsewhere. Only significant if Repeat is set.

public XButton insertButton(XActionListener _xActionListener, int _nPosX, int _nPosY, int _nWidth, String _sLabel, short _nPushButtonType) {
    XButton xButton = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "CommandButton");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oButtonModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlButtonModel");
        XMultiPropertySet xButtonMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oButtonModel);
        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xButtonMPSet.setPropertyValues(
        new String[] {"Height", "Label", "Name", "PositionX", "PositionY", "PushButtonType", "Width" } ,
        new Object[] {new Integer(14), _sLabel, sName, new Integer(_nPosX), new Integer(_nPosY), new Short(_nPushButtonType), new Integer(_nWidth)});

        // add the model to the NameContainer of the dialog model
        m_xDlgModelNameContainer.insertByName(sName, oButtonModel);
        XControl xButtonControl = m_xDlgContainer.getControl(sName);
        xButton = (XButton) UnoRuntime.queryInterface(XButton.class, xButtonControl);
        // An ActionListener will be notified on the activation of the button...
        xButton.addActionListener(_xActionListener);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xButton;
}

In the example, an action listener is attached to the command button. An action listener implements the interface <idl>com.sun.star.awt.XActionListener</idl> and its method actionPerformed() is invoked when the user clicks on the button. (see also Events).

The following code snippet shows an example of how to use the action listener.

public void actionPerformed(ActionEvent rEvent) {
    try {
        // get the control that has fired the event,
        XControl xControl = (XControl) UnoRuntime.queryInterface(XControl.class, rEvent.Source);
        XControlModel xControlModel = xControl.getModel();
        XPropertySet xPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xControlModel);
        String sName = (String) xPSet.getPropertyValue("Name");
        // just in case the listener has been added to several controls,
        // we make sure we refer to the right one
        if (sName.equals("CommandButton1")) {
            //...
        }
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
}

Graphics

When an image source is used several times it may be better to keep the image in its own object variable. The following code snippet shows how you can create such a variable:

// creates a UNO graphic object that can be used to be assigned
// to the property "Graphic" of a controlmodel
public XGraphic getGraphic(String _sImageUrl) {
    XGraphic xGraphic = null;
    try {
        // create a GraphicProvider at the global service manager...
        Object oGraphicProvider = m_xMCF.createInstanceWithContext("com.sun.star.graphic.GraphicProvider", m_xContext);
        XGraphicProvider xGraphicProvider = (XGraphicProvider) UnoRuntime.queryInterface(XGraphicProvider.class, oGraphicProvider);
        // create the graphic object
        PropertyValue[] aPropertyValues = new PropertyValue[1];
        PropertyValue aPropertyValue = new PropertyValue();
        aPropertyValue.Name = "URL";
        aPropertyValue.Value = _sImageUrl;
        aPropertyValues[0] = aPropertyValue;
        xGraphic = xGraphicProvider.queryGraphic(aPropertyValues);
        return xGraphic;
    } catch (com.sun.star.uno.Exception ex) {
        throw new java.lang.RuntimeException("cannot happen...");
    }
}

This object variable may be assigned to the property Graphic that is also supported by image controls Image Control, check boxes Check Box, radio buttons Radio Button and command buttons. Note: Issue https://www.openoffice.org/issues/show_bug.cgi?id=76718 has not yet been resolved. The graphic may only be assigned to the control after the peer of the dialog has been created (see Displaying Dialogs).

Image Control

If you want to display an image without the command button functionality, the image control <idl>com.sun.star.awt.UnoControlImageControl</idl> and its model <idl>com.sun.star.awt.UnoControlImageControlModel</idl> is the control of choice. The location of the graphic for the command button is set by the ImageURL property. Usually, the size of the image does not match the size of the control, therefore the image control automatically scales the image to the size of the control by setting the ScaleImage property to true.

One problem with URLs in LibreOffice is that the developer, in certain contexts, may only know the system dependent path to his or her image file. A system path is not accepted by ImageURL. The following example shows how you can convert this path to a URL that can then be passed to the property ImageURL.

public void insertImageControl(XMultiComponentFactory _xMCF, String _sImageSystemPath, int _nPosX, int _nPosY, int _nHeight, int _nWidth) {
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "ImageControl");
        // convert the system path to the image to a FileUrl
        java.io.File oFile = new java.io.File(_sImageSystemPath);
        Object oFCProvider = _xMCF.createInstanceWithContext("com.sun.star.ucb.FileContentProvider", this.m_xContext);
        XFileIdentifierConverter xFileIdentifierConverter = (XFileIdentifierConverter) UnoRuntime.queryInterface(XFileIdentifierConverter.class, oFCProvider);
        String sImageUrl = xFileIdentifierConverter.getFileURLFromSystemPath(_sImageSystemPath, oFile.getAbsolutePath());
        XGraphic xGraphic = getGraphic(sImageUrl);

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oICModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlImageControlModel");
        XMultiPropertySet xICModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oICModel);

        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        // The image is not scaled
        xICModelMPSet.setPropertyValues(
        new String[] {"Border", "Graphic", "Height", "Name", "PositionX", "PositionY", "ScaleImage", "Width"},
        new Object[] { new Short((short) 1), xGraphic, new Integer(_nHeight), sName, new Integer(_nPosX), new Integer(_nPosY), Boolean.FALSE, new Integer(_nWidth)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oICModel);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
}

// creates a UNO graphic object that can be used to be assigned
// to the property "Graphic" of a controlmodel
public XGraphic getGraphic(String _sImageUrl) {
    XGraphic xGraphic = null;
    try {
        // create a GraphicProvider at the global service manager...
        Object oGraphicProvider = m_xMCF.createInstanceWithContext("com.sun.star.graphic.GraphicProvider", m_xContext);
        XGraphicProvider xGraphicProvider = (XGraphicProvider) UnoRuntime.queryInterface(XGraphicProvider.class, oGraphicProvider);
        // create the graphic object
        PropertyValue[] aPropertyValues = new PropertyValue[1];
        PropertyValue aPropertyValue = new PropertyValue();
        aPropertyValue.Name = "URL";
        aPropertyValue.Value = _sImageUrl;
        aPropertyValues[0] = aPropertyValue;
        xGraphic = xGraphicProvider.queryGraphic(aPropertyValues);
        return xGraphic;
    } catch (com.sun.star.uno.Exception ex) {
        throw new java.lang.RuntimeException("cannot happen...");
    }
}

Extension developers will be confronted with the problem that the graphic to be displayed by the image is located within the extension file. OpenOffice.org version 2.3 provided a simple method to query the path of the extension, see Location of Installed Extensions.

For previous versions of LibreOffice a manual workaround can be used, see description hereunder.

The path to the images of the extension should be set in a configuration file of the component For example:

..
<prop oor:name="Images" oor:type="xs:string">
    <value>%origin%/images</value>
</prop>

The variable %origin% will be automatically assigned the value of the URL of the component file when this entry is queried during runtime:

/**
* @param _sRegistryPath the path a registryNode
* @param _sImageName the name of the image
*/
public String getImageUrl(String _sRegistryPath, String _sImageName) {
String sImageUrl = "";
    try {
        // retrive the configuration node of the extension
        XNameAccess xNameAccess = getRegistryKeyContent(_sRegistryPath);
        if (xNameAccess != null) {
            if (xNameAccess.hasByName(_sImageName)) {
                // get the Image Url and process the Url by the macroexpander...
                sImageUrl = (String) xNameAccess.getByName(_sImageName);
                Object oMacroExpander = this.m_xContext.getValueByName("/singletons/com.sun.star.util.theMacroExpander");
                XMacroExpander xMacroExpander = (XMacroExpander) UnoRuntime.queryInterface(XMacroExpander.class, oMacroExpander);
                sImageUrl = xMacroExpander.expandMacros(sImageUrl);
                sImageUrl = sImageUrl.substring(new String("vnd.sun.star.expand:").length(), sImageUrl.length());
                sImageUrl = sImageUrl.trim();
                sImageUrl += "/" + _sImageName;
            }
        }
    } catch (Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        */
        ex.printStackTrace(System.out);
    }
    return sImageUrl;
}

/**
* @param _sKeyName
* @return
*/
public XNameAccess getRegistryKeyContent(String _sKeyName) {
    try {
        Object oConfigProvider;
        PropertyValue[] aNodePath = new PropertyValue[1];
        oConfigProvider = m_xMCF.createInstanceWithContext("com.sun.star.configuration.ConfigurationProvider", this.m_xContext);
        aNodePath[0] = new PropertyValue();
        aNodePath[0].Name = "nodepath";
        aNodePath[0].Value = _sKeyName;
        XMultiServiceFactory xMSFConfig = (XMultiServiceFactory) UnoRuntime.queryInterface(XMultiServiceFactory.class, oConfigProvider);
        Object oNode = xMSFConfig.createInstanceWithArguments("com.sun.star.configuration.ConfigurationAccess", aNodePath);
        XNameAccess xNameAccess = (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class, oNode);
        return xNameAccess;
    } catch (Exception exception) {
        exception.printStackTrace(System.out);
        return null;
    }
}

For further information about the development of extensions and configuration file handling, please see Integrating Components into LibreOffice).

Check Box

The check box control model <idl>com.sun.star.awt.UnoControlCheckBoxModel</idl>is used in groups to display multiple choices. When a check box is selected it displays a check mark. Check boxes work independently of each other. A user can select any number or combination of check boxes. The State property of the model service <idl>com.sun.star.awt.UnoControlCheckBoxModel</idl> defines three values, where 0 is not checked, 1 is checked, and 2 is undetermined. You can enable the tri-state mode of a check box by setting the TriState property to True. A tri-state check box used to give the user the option of setting or unsetting an option.

public XCheckBox insertCheckBox(XItemListener _xItemListener, int _nPosX, int _nPosY, int _nWidth) {
XCheckBox xCheckBox = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "CheckBox");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oCBModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlCheckBoxModel");

        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        XMultiPropertySet xCBMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oCBModel);
        xCBMPSet.setPropertyValues(
        new String[] {"Height", "Label", "Name", "PositionX", "PositionY", "Width" } ,
        new Object[] {new Integer(8), "~Include page number", sName, new Integer(_nPosX), new Integer(_nPosY), new Integer(_nWidth)});

        // The following property may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        XPropertySet xCBModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xCBMPSet);
        xCBModelPSet.setPropertyValue("TriState", Boolean.TRUE);
        xCBModelPSet.setPropertyValue("State", new Short((short) 1));

        // add the model to the NameContainer of the dialog model
        m_xDlgModelNameContainer.insertByName(sName, oCBModel);
        XControl xCBControl = m_xDlgContainer.getControl(sName);
        xCheckBox = (XCheckBox) UnoRuntime.queryInterface(XCheckBox.class, xCBControl);
        // An ActionListener will be notified on the activation of the button...
        xCheckBox.addItemListener(_xItemListener);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xCheckBox;
}

In this example, a <idl>com.sun.star.awt.XItemListener</idl> is attached to the checkbox control. This listener is notified on each change of the State property in the control model. Listeners on check boxes are often used to enable or disable controls whose functionality is dependent on the state of a checkbox:

public void itemStateChanged(ItemEvent itemEvent) {
    try {
        // retrieve the control that the event has been invoked at...
        XCheckBox xCheckBox = (XCheckBox) UnoRuntime.queryInterface(XCheckBox.class, itemEvent.Source);
        // retrieve the control that we want to disable or enable
        XControl xControl = (XControl) UnoRuntime.queryInterface(XControl.class, m_xDlgContainer.getControl("CommandButton1"));
        XPropertySet xModelPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xControl.getModel());
        short nState = xCheckBox.getState();
        boolean bdoEnable = true;
        switch (nState) {
            case 1: // checked
                bdoEnable = true;
                break;
            case 0: // not checked
            case 2: // don't know
                bdoEnable = false;
                break;
        }
        // Alternatively we could have done it also this way:
        // bdoEnable = (nState == 1);
        xModelPropertySet.setPropertyValue("Enabled", new Boolean(bdoEnable));
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.beans.PropertyVetoException
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
}

A checkbox may also display images similar to a button as described in Command Button.

Radio Button

A radio button control model <idl>com.sun.star.awt.UnoControlRadioButtonModel</idl> is a simple switch with two states selected by the user. Usually these controls are used in groups to display several options that the user may select. While they are very similar to check boxes, selecting one radio button deselects all the radio buttons in the same group. To assemble several radio buttons to a control group it is important to know that there may not be any control TabIndex between the tab indices of the radio buttons although it is not necessary for the tab indices to be directly consecutive. Two groups of radio buttons can be separated by any control with a tab index that is between the tab indices of the two groups. Usually a group box, or horizontal and vertical lines are used because those controls visually group the radio buttons together. In principal, any control can be used to separate groups of radio buttons. There is no functional relationship between a radio button and a group box Group Box. The state of an radio button is accessed by the State property in the service <idl>com.sun.star.awt.UnoControlRadioButtonModel</idl>, where 0 is not checked and 1 is checked.

A radio button may also display images similar to a button as described in Command Button.

The following example demonstrates the way a group of two radio buttons may be created. Note the assignment of the tab indices to each radio button.

public void insertRadioButtonGroup(short _nTabIndex, int _nPosX, int _nPosY, int _nWidth) {
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "OptionButton");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oRBModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlRadioButtonModel");
        XMultiPropertySet xRBMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oRBModel);
        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xRBMPSet.setPropertyValues(
        new String[] {"Height", "Label", "Name", "PositionX", "PositionY", "State", "TabIndex", "Width" } ,
        new Object[] {new Integer(8), "~First Option", sName, new Integer(_nPosX), new Integer(_nPosY), new Short((short) 1), new Short(_nTabIndex++),new Integer(_nWidth)});
        // add the model to the NameContainer of the dialog model
        m_xDlgModelNameContainer.insertByName(sName, oRBModel);

        // create a unique name by means of an own implementation...
        sName = createUniqueName(m_xDlgModelNameContainer, "OptionButton");

        oRBModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlRadioButtonModel");
        xRBMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oRBModel);
        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xRBMPSet.setPropertyValues(
        new String[] {"Height", "Label", "Name", "PositionX", "PositionY", "TabIndex", "Width" } ,
        new Object[] {new Integer(8), "~Second Option", sName, new Integer(130), new Integer(214), new Short(_nTabIndex), new Integer(150)});
        // add the model to the NameContainer of the dialog model
        m_xDlgModelNameContainer.insertByName(sName, oRBModel);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
}

Scroll Bar

A <idl>com.sun.star.awt.UnoControlScrollBar</idl> can be used to display arbitrary content. This can be content that is too large in size to fit into a dialog or any other measurable content. It offers assistance to the user for the navigation through a container, like a group of controls. The user positions the thumb in the scroll bar to determine which part of the content is to be displayed in the viewing area of the dialog. The component that uses the scroll bar then typically adjusts the display so that the end of the scroll bar represents the end of the contents that can be displayed, or 100%. The start of the scroll bar is the beginning of the content that can be displayed, or 0%. The position of the thumb within those bounds then translates to the corresponding percentage representing the position within the total content.

Typically a <idl>com.sun.star.awt.XAdjustmentListener</idl> is added to the control by means of the method addAdjustmentListener() of the interface <idl>com.sun.star.awt.XScrollBar</idl>. The method adjustmentValueChanged is called each time the position of the thumb in the scroll bar changes. The model <idl>com.sun.star.awt.UnoControlScrollBarModel</idl> offers the following properties:

Properties of <idl>com.sun.star.awt.UnoControlScrollBarModel</idl>
<idlm>com.sun.star.awt.UnoControlScrollBarModel:ScrollValue</idlm> long. The ScrollValue property represents the position of the thumb.
<idlm>com.sun.star.awt.UnoControlScrollBarModel:LineIncrement</idlm> long. The LineIncrement property specifies the change of the scroll value per mouse click on an arrow.
<idlm>com.sun.star.awt.UnoControlScrollBarModel:BlockIncrement</idlm> long. The BlockIncrement property specifies the change of the Scrollvalue property when clicking in a scroll bar in the region between the thumb and and the arrows.
<idlm>com.sun.star.awt.UnoControlScrollBarModel:Orientation</idlm> long. Specifies the orientation of the scroll bar. Accepts either com.sun.star.awt.ScrollBarOrientation.VERTICAL or com.sun.star.awt.ScrollBarOrientation.HORIZONTAL
<idlm>com.sun.star.awt.UnoControlScrollBarModel:RepeatDelay</idlm> long. Specifies the delay in milliseconds between repeating events. A repeating event occurs when clicking on a button or the background of a scroll bar while keeping the mouse button pressed for some time.
<idlm>com.sun.star.awt.UnoControlScrollBarModel:ScrollValueMin</idlm> long. The ScrollValueMin property defines the minimum value of the Scrollvalue property.
<idlm>com.sun.star.awt.UnoControlScrollBarModel:ScrollValueMax</idlm> long. The ScrollValueMax property defines the maximum value of the Scrollvalue property.
<idlm>com.sun.star.awt.UnoControlScrollBarModel:VisibleSize</idlm> long. The property VisibleSize defines the visible size of the thumb and represents the percentage of the currently visible content and the total content that can be displayed.

You can also set these attributes <idl>com.sun.star.awt.XScrollBar</idl> interface.

This example demonstrates how you can set up a scroll bar:

public XPropertySet insertVerticalScrollBar(XAdjustmentListener _xAdjustmentListener, int _nPosX, int _nPosY, int _nHeight) {
    XPropertySet xSBModelPSet = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "ScrollBar");

        Integer NOrientation = new Integer(com.sun.star.awt.ScrollBarOrientation.VERTICAL);

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oSBModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlScrollBarModel");
        XMultiPropertySet xSBModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oSBModel);
        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xSBModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "Orientation", "PositionX", "PositionY", "Width"},
        new Object[] { new Integer(_nHeight), sName, NOrientation, new Integer(_nPosX), new Integer(_nPosY), new Integer(8)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oSBModel);

        xSBModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oSBModel);
        // The following properties may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        xSBModelPSet.setPropertyValue("ScrollValueMin", new Integer(0));
        xSBModelPSet.setPropertyValue("ScrollValueMax", new Integer(100));
        xSBModelPSet.setPropertyValue("ScrollValue", new Integer(5));
        xSBModelPSet.setPropertyValue("LineIncrement", new Integer(2));
        xSBModelPSet.setPropertyValue("BlockIncrement", new Integer(10));

        // Add an Adjustment that will listen to changes of the scrollbar...
        XControl xSBControl = m_xDlgContainer.getControl(sName);
        XScrollBar xScrollBar = (XScrollBar) UnoRuntime.queryInterface(XScrollBar.class, xSBControl);
        xScrollBar.addAdjustmentListener(_xAdjustmentListener);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xSBModelPSet;
}

The adjustmentListener, that has been added to the example scroll bar must implement the method adjustmentValueChanged():

public void adjustmentValueChanged(AdjustmentEvent _adjustmentEvent) {
    switch (_adjustmentEvent.Type.getValue()) {
        case AdjustmentType.ADJUST_ABS_value:
            System.out.println( "The event has been triggered by dragging the thumb..." );
            break;
        case AdjustmentType.ADJUST_LINE_value:
            System.out.println( "The event has been triggered by a single line move.." );
            break;
        case AdjustmentType.ADJUST_PAGE_value:
            System.out.println( "The event has been triggered by a block move..." );
            break;
    }
    System.out.println( "The value of the scrollbar is: " + _adjustmentEvent.Value);
}

List Box

The list box control <idl>com.sun.star.awt.UnoControlListBox</idl> displays a list of items that the user can select one or more of. If the number of items exceeds what can be displayed in the list box, scroll bars automatically appear on the control. The model of a list box supports the service <idl>com.sun.star.awt.UnoControlListBoxModel</idl> :

Properties of <idl>com.sun.star.awt.UnoControlListBoxModel</idl>
<idlm>com.sun.star.awt.UnoControlListBoxModel:Dropdown</idlm> boolean. If the Dropdown property is set to true, the list of items is displayed in a drop-down box.
<idlm>com.sun.star.awt.UnoControlListBoxModel:LineCount</idlm> short. If the Dropdown property is set to true, the maximum number of line counts in the drop- down box are specified with the LineCount property.
<idlm>com.sun.star.awt.UnoControlListBoxModel:MultiSelection</idlm> boolean. If the MultiSelection property is set to true, more than one entry can be selected. This property is ignored if Dropdown is set to true.
<idlm>com.sun.star.awt.UnoControlListBoxModel:StringItemList</idlm> string[]. A sequence of strings containing the actual list of items within the list box.
<idlm>com.sun.star.awt.UnoControlListBoxModel:SelectedItems</idlm> short[]. A sequence of strings containing the actual list of indices of all selected items.

The list box allows you to register a <idl>com.sun.star.awt.XItemListener</idl> as well as a <idl>com.sun.star.awt.XActionListener</idl>. Double-clicking a list box item will invoke the method actionPerformed() of the action listener. If items are selected with a single click or even programmatically, the method itemStateChanged() is called when an item listener is registered at the list box control.

The list box control that supports the interface <idl>com.sun.star.awt.XListBox</idl> offers more convenient functions than the list box model. For example, it offers the method selectItemPos( [in] short nPos,[in] boolean bSelect ) to select or deselect a single item in the list box. As can be seen in the following example, to achieve the same result with the model, a sequence of all selected list box item indices must be assigned.

public XListBox insertListBox(int _nPosX, int _nPosY, int _nWidth, int _nStep, String[] _sStringItemList) {
    XListBox xListBox = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "ListBox");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oListBoxModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlListBoxModel");
        XMultiPropertySet xLBModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oListBoxModel);
        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xLBModelMPSet.setPropertyValues(
        new String[] {"Dropdown", "Height", "Name", "PositionX", "PositionY", "Step", "StringItemList", "Width" } ,
        new Object[] {Boolean.TRUE, new Integer(12), sName, new Integer(_nPosX), new Integer(_nPosY), new Integer(_nStep), _sStringItemList, new Integer(_nWidth)});
        // The following property may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        XPropertySet xLBModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xLBModelMPSet);
        xLBModelPSet.setPropertyValue("MultiSelection", Boolean.TRUE);
        short[] nSelItems = new short[] {(short) 1, (short) 3};
        xLBModelPSet.setPropertyValue("SelectedItems", nSelItems);
        // add the model to the NameContainer of the dialog model
        m_xDlgModelNameContainer.insertByName(sName, xLBModelMPSet);
        XControl xControl = m_xDlgContainer.getControl(sName);
        // retrieve a ListBox that is more convenient to work with than the Model of the ListBox...
        xListBox = (XListBox) UnoRuntime.queryInterface(XListBox.class, xControl);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xListBox;
}

Combo Box

A combo box control presents a list of items to the user. It also contains a text field allowing the user to input text that is not in the list. A combo box is used when there is a list of suggested choices, whereas a list box is used when the user's input is limited only to the list. The features and properties of a combo box and a list box are similar. As can be seen in <idl>com.sun.star.awt.UnoControlComboBox</idl> the combo box includes the functionality of a <idl>com.sun.star.awt.UnoControlEdit</idl>, which also allows you to add an <idl>com.sun.star.awt.XTextListener</idl> to the combo box. The text displayed in the field of the combo box can be controlled by the Text property of the combo box model that supports the service <idl>com.sun.star.awt.UnoControlComboBoxModel</idl>. Just like in the list box, the actual list of items is accessible through the StringItemList property. A useful feature of the model is the automatic word completion that can be activated by setting the property Autocomplete to true.

You can control the items in a combo box via the interface <idl>com.sun.star.awt.XComboBox</idl> at the control, which offers a more convenient access to the control's functionality.

public XComboBox insertComboBox(int _nPosX, int _nPosY, int _nWidth) {
    XComboBox xComboBox = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "ComboBox");

        String[] sStringItemList = new String[]{"First Entry", "Second Entry", "Third Entry", "Fourth Entry"};

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oComboBoxModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlComboBoxModel");
        XMultiPropertySet xCbBModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oComboBoxModel);
        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xCbBModelMPSet.setPropertyValues(
        new String[] {"Dropdown", "Height", "Name", "PositionX", "PositionY", "StringItemList", "Width" } ,
        new Object[] {Boolean.TRUE, new Integer(12), sName, new Integer(_nPosX), new Integer(_nPosY), sStringItemList, new Integer(_nWidth)});

        // The following property may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        XPropertySet xCbBModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xCbBModelMPSet);
        xCbBModelPSet.setPropertyValue("MaxTextLen", new Short((short) 10));
        xCbBModelPSet.setPropertyValue("ReadOnly", Boolean.FALSE);

        // add the model to the NameContainer of the dialog model
        m_xDlgModelNameContainer.insertByName(sName, xCbBModelMPSet);
        XControl xControl = m_xDlgContainer.getControl(sName);

        // retrieve a ListBox that is more convenient to work with than the Model of the ListBox...
        xComboBox = (XComboBox) UnoRuntime.queryInterface(XComboBox.class, xControl);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xComboBox;
}

Progress Bar

The progress bar control <idl>com.sun.star.awt.UnoControlProgressBar</idl> displays a growing or shrinking bar to give the user feedback during a persisting task. The minimum and the maximum progress value of the control is set by the ProgressValueMin and the ProgressValueMax properties of the control model that supports the service <idl>com.sun.star.awt.UnoControlProgressBarModel</idl> . The progress value is controlled by the ProgressValue property. The fill color can be changed by setting the property FillColor. The control implements the interface <idl>com.sun.star.awt.XProgressBar</idl> which allows you to control the progress bar. The progress bar interface <idl>com.sun.star.awt.XReschedule</idl> helps to update and repaint the progress bar while a concurrent task is running, but this interface interrupts the main thread of the office. Issue https://www.openoffice.org/issues/show_bug.cgi?id=i71425 is assigned to find an appropriate solution for this problem.

public XPropertySet insertProgressBar(int _nPosX, int _nPosY, int _nWidth, int _nProgressMax) {
    XPropertySet xPBModelPSet = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "ProgressBar");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oPBModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlProgressBarModel");

        XMultiPropertySet xPBModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oPBModel);
        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xPBModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "PositionX", "PositionY", "Width"},
        new Object[] { new Integer(8), sName, new Integer(_nPosX), new Integer(_nPosY), new Integer(_nWidth)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oPBModel);
        xPBModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oPBModel);

        // The following properties may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        xPBModelPSet.setPropertyValue("ProgressValueMin", new Integer(0));
        xPBModelPSet.setPropertyValue("ProgressValueMax", new Integer(_nProgressMax));
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xPBModelPSet;
}

Horizontal/Vertical Line Control

The line control service <idl>com.sun.star.awt.UnoControlFixedLine</idl> describes the behavior of simple lines in a dialog. In most cases, the line control is used to visually subdivide a dialog. The line control may provide horizontal or vertical orientation which is determined by the Orientation property of the model as specified in <idl>com.sun.star.awt.UnoControlFixedLineModel</idl>. The label of a line control is set by the Label property. The label is only displayed if the control has a horizontal orientation.

This example inserts a line with a horizontal orientation (Orientation == 0) in a dialog:

public void insertHorizontalFixedLine(int _nPosX, int _nPosY, int _nWidth, String _sLabel) {
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "FixedLine");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oFLModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlFixedLineModel");
        XMultiPropertySet xFLModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oFLModel);

        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xFLModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "Orientation", "PositionX", "PositionY", "Width"},
        new Object[] { new Integer(2), sName, new Integer(0), new Integer(_nPosX), new Integer(_nPosY), new Integer(_nWidth)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oFLModel);

        // The following property may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        XPropertySet xFLPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oFLModel);
        xFLPSet.setPropertyValue("Label", _sLabel);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
}

Group Box

The group box control <idl>com.sun.star.awt.UnoControlGroupBox</idl> creates a frame to visually group other controls together, such as option buttons and check boxes. Controls can be added to the group box at any time. The group box control does not provide any container functionality for other controls, it is merely a visual control, and is always transparent. The group box contains a label embedded within the border and is set by the Label property. LibreOffice uses fixed lines Horizontal/Vertical Line Control to visually subdivide a dialog into logical control groups.

public void insertGroupBox(int _nPosX, int _nPosY, int _nHeight, int _nWidth) {
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "FrameControl");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oGBModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlGroupBoxModel");
        XMultiPropertySet xGBModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oGBModel);

        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xGBModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "PositionX", "PositionY", "Width"},
        new Object[] { new Integer(80), sName, new Integer(106), new Integer(114), new Integer(100)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oGBModel);

        // The following property may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        XPropertySet xGBPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oGBModel);
        xGBPSet.setPropertyValue("Label", "~My GroupBox");
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
}

Text Field

The text field, described by the service <idl>com.sun.star.awt.UnoControlEdit</idl> and its respective model - specified in <idl>com.sun.star.awt.UnoControlEditModel</idl> - is used to receive input from the user during runtime. As can be seen in the following table, most of the control settings can also be applied to the model. When a text field receives the focus by pressing the TAB key, the displayed text is selected and highlighted by default. The default cursor position within the text field is to the right of the existing text. If the user starts typing while a block of text is selected, the selected text is replaced. In some cases, the user may change the default selection behavior and set the selection manually. This is done using the <idl>com.sun.star.awt.XTextComponent</idl> interface.

Properties of <idl>com.sun.star.awt.UnoControlEditModel</idl>
<idlm>com.sun.star.awt.UnoControlEditModel:EchoChar</idlm> short. The UnoControlEditModel control is also commonly used for entering passwords. The property EchoChar specifies the Unicode index of the character that is displayed in the text field while the user enters the password. In this context, the MaxTextLen property is used to limit the number of characters that are typed in.
<idlm>com.sun.star.awt.UnoControlEditModel:HardLineBreaks</idlm> boolean. Specifies if hard line breaks are included in the text returned by the Text property.
<idlm>com.sun.star.awt.UnoControlEditModel:HideInactiveSelection</idlm> boolean. Specifies whether selected text within the control remains selected when the focus is not on the control. The default is true and hides the selection.
<idlm>com.sun.star.awt.UnoControlEditModel:MaxTextLen</idlm> short. The maximum number of characters that can be entered by the user is specified with the MaxTextLen property. A value of 0 means that there is no limitation.
<idlm>com.sun.star.awt.UnoControlEditModel:MultiLine</idlm> boolean. By default, a UnoControlEdit displays a single line of text. This behavior is changed by setting the property MultiLine to true.
<idlm>com.sun.star.awt.UnoControlEditModel:LineEndFormat</idlm> short. A value of the constant group <idl>com.sun.star.awt.LineEndFormat</idl> that defines the character denoting the line end if MultiLine is set to true.
<idlm>com.sun.star.awt.UnoControlEditModel:ReadOnly</idlm> boolean. In general, the text field is used for text that can be edited. It can be set read-only by setting the ReadOnly property to true.
<idlm>com.sun.star.awt.UnoControlEditModel:Text</idlm> The actual text displayed in a text field is controlled by the Text property.
<idlm>com.sun.star.awt.UnoControlEditModel:VScroll</idlm> boolean. The HScroll and VScroll properties are used to display a horizontal or vertical scroll bar to scroll the content in either direction. The properties are ignored if MultiLine is set to false.
<idlm>com.sun.star.awt.UnoControlEditModel:HScroll</idlm>

This example demonstrates how you can use a UnoControlEditControl:

public XTextComponent insertEditField(XTextListener _xTextListener, XFocusListener _xFocusListener, int _nPosX, int _nPosY, int _nWidth) {
    XTextComponent xTextComponent = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "TextField");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oTFModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlEditModel");
        XMultiPropertySet xTFModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oTFModel);

        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xTFModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "PositionX", "PositionY", "Text", "Width"},
        new Object[] { new Integer(12), sName, new Integer(_nPosX), new Integer(_nPosY), "MyText", new Integer(_nWidth)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oTFModel);
        XPropertySet xTFModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oTFModel);

        // The following property may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        xTFModelPSet.setPropertyValue("EchoChar", new Short((short) '*'));
        XControl xTFControl = m_xDlgContainer.getControl(sName);

        // add a textlistener that is notified on each change of the controlvalue...
        xTextComponent = (XTextComponent) UnoRuntime.queryInterface(XTextComponent.class, xTFControl);
        XWindow xTFWindow = (XWindow) UnoRuntime.queryInterface(XWindow.class, xTFControl);
        xTFWindow.addFocusListener(_xFocusListener);
        xTextComponent.addTextListener(_xTextListener);
        xTFWindow.addKeyListener(this);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xTextComponent;
}

The text listener must implement the method textChanged:

public void textChanged(TextEvent textEvent) {
    try {
        // get the control that has fired the event,
        XControl xControl = (XControl) UnoRuntime.queryInterface(XControl.class, textEvent.Source);
        XControlModel xControlModel = xControl.getModel();
        XPropertySet xPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xControlModel);
        String sName = (String) xPSet.getPropertyValue("Name");
        // just in case the listener has been added to several controls,
        // we make sure we refer to the right one
        if (sName.equals("TextField1")) {
            String sText = (String) xPSet.getPropertyValue("Text");
            System.out.println(sText);
            // insert your code here to validate the text of the control...
        }
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
}

The control that supports the interface <idl>com.sun.star.awt.XTextComponent</idl> offers additional methods to query and set selections and insert part texts in the control.

Text Field Extensions

A user can enter any kind of data into a text field. These values are always stored as a string in the Text property. This can cause some problems when you are evaluating the user input. These controls offer specific solutions to this issue:

  • Formatted field.
  • Date field.
  • Time field.
  • Currency field.
  • Numeric field.
  • Pattern field.
Common Properties of Extensions of a UnoControlEdit (text field)
[IDLS:StrictFormat] boolean. If set to true, only the allowed characters as defined by the format of the control are accepted. All other entries typed with the keyboard are ignored.
[IDLS:EnforceFormat] boolean. If set to true, the allowed characters are checked when leaving the focus.
[IDLS:Spin] boolean. The Spin property defines whether the control displays a spin button.

Formatted Field

The formatted field control <idl>com.sun.star.awt.UnoControlFormattedField</idl> specifies a format that is used for formatting the entered and displayed data.

Properties of <idl>com.sun.star.awt.UnoControlFormattedFieldModel</idl>
<idlm>com.sun.star.awt.UnoControlFormattedFieldModel:TreatAsNumber</idlm> boolean. If the TreatAsNumber property is set to true, the text of the control is interpreted as a number.
<idlm>com.sun.star.awt.UnoControlFormattedFieldModel:FormatsSupplier</idlm> The FormatsSupplier property returns a <idl>com.sun.star.util.XNumberFormatsSupplier</idl>. that offers access to the number format of the control. Initially, when no number formats supplier is assigned, a default number formatter is set. Further information about the management of number formats can be found in Number Formats.
<idlm>com.sun.star.awt.UnoControlFormattedFieldModel:FormatKey</idlm> long. The unique key that represents the number format of the control may be set an queried by the property FormatKey.
<idlm>com.sun.star.awt.UnoControlFormattedFieldModel:EffectiveDefault</idlm> any. Specifies the default value of the control. Depending on the value of TreatAsNumber, this may be a string or a numeric (double) value.
<idlm>com.sun.star.awt.UnoControlFormattedFieldModel:EffectiveMax</idlm> double. Specifies the maximum value that the user may enter.
<idlm>com.sun.star.awt.UnoControlFormattedFieldModel:EffectiveMin</idlm> double. Specifies the minimum value that the user may enter.
<idlm>com.sun.star.awt.UnoControlFormattedFieldModel:EffectiveValue</idlm> any. Specifies the current value of the control. In dependence on the value of TreatAsNumber this may be a string or a numeric (double) value.

As any kind of number format at the model of the formatted field may be set, this control can be universally used instead of the date field, time field, numeric field or currency field controls that are designed for special purposes as described in the following sections.

The following example demonstrates the creation of a formatted field. One critical point is to assign the NumberFormatsSupplier to the property FormatsSupplier. In the example, this is created directly at the global ServiceManager (m_xMCF). It is also possible to assign an existing NumberFormatsSupplier, like a spreadsheet document or a text document.

public XPropertySet insertFormattedField(XSpinListener _xSpinListener, int _nPosX, int _nPosY, int _nWidth) {
    XPropertySet xFFModelPSet = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "FormattedField");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oFFModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlFormattedFieldModel");
        XMultiPropertySet xFFModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oFFModel);
        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xFFModelMPSet.setPropertyValues(
            new String[] {"EffectiveValue", "Height", "Name", "PositionX", "PositionY", "StrictFormat", "Spin", "Width"},
            new Object[] { new Double(12348), new Integer(12), sName, new Integer(_nPosX), new Integer(_nPosY), Boolean.TRUE, Boolean.TRUE, new Integer(_nWidth)});

        xFFModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oFFModel);
        // to define a numberformat you always need a locale...
        com.sun.star.lang.Locale aLocale = new com.sun.star.lang.Locale();
        aLocale.Country = "US";
        aLocale.Language = "en";
        // this Format is only compliant to the english locale!
        String sFormatString = "NNNNMMMM DD, YYYY";

        // a NumberFormatsSupplier has to be created first "in the open countryside"...
        Object oNumberFormatsSupplier = m_xMCF.createInstanceWithContext("com.sun.star.util.NumberFormatsSupplier", m_xContext);
        XNumberFormatsSupplier xNumberFormatsSupplier = (XNumberFormatsSupplier) UnoRuntime.queryInterface(XNumberFormatsSupplier.class, oNumberFormatsSupplier);
        XNumberFormats xNumberFormats = xNumberFormatsSupplier.getNumberFormats();
        // is the numberformat already defined?
        int nFormatKey = xNumberFormats.queryKey(sFormatString, aLocale, true);
        if (nFormatKey == -1) {
            // if not then add it to the NumberFormatsSupplier
            nFormatKey = xNumberFormats.addNew(sFormatString, aLocale);
        }

        // The following property may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        xFFModelPSet.setPropertyValue("FormatsSupplier", xNumberFormatsSupplier);
        xFFModelPSet.setPropertyValue("FormatKey", new Integer(nFormatKey));

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oFFModel);

        // finally we add a Spin-Listener to the control
        XControl xFFControl = m_xDlgContainer.getControl(sName);
        // add a SpinListener that is notified on each change of the controlvalue...
        XSpinField xSpinField = (XSpinField) UnoRuntime.queryInterface(XSpinField.class, xFFControl);
        xSpinField.addSpinListener(_xSpinListener);

    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xFFModelPSet;
}

The attached spin listener in this code example must implement <idl>com.sun.star.awt.XSpinListener</idl> which, among other things, includes up()

public void up(SpinEvent spinEvent) {
    try {
        // get the control that has fired the event,
        XControl xControl = (XControl) UnoRuntime.queryInterface(XControl.class, spinEvent.Source);
        XControlModel xControlModel = xControl.getModel();
        XPropertySet xPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xControlModel);
        String sName = (String) xPSet.getPropertyValue("Name");
        // just in case the listener has been added to several controls,
        // we make sure we refer to the right one
        if (sName.equals("FormattedField1")) {
            double fvalue = AnyConverter.toDouble(xPSet.getPropertyValue("EffectiveValue"));
            System.out.println("Controlvalue: " + fvalue);
            // insert your code here to validate the value of the control...
        }
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
}

public void down(SpinEvent spinEvent) {
}

public void last(SpinEvent spinEvent) {
}

public void first(SpinEvent spinEvent) {
}

public void disposing(EventObject rEventObject) {
}

Numeric Field

For developers who want to use a simple numeric field control and find the number formatter too difficult to handle, they can use the numeric field control <idl>com.sun.star.awt.UnoControlNumericField</idl>. The control model, specified in <idl>com.sun.star.awt.UnoControlNumericFieldModel</idl> is simple to set up as the following table illustrates:

Properties of <idl>com.sun.star.awt.UnoControlNumericFieldModel</idl>
<idlm>com.sun.star.awt.UnoControlNumericFieldModel:DecimalAccuracy</idlm> short. The DecimalAccuracy property specifies the number of digits displayed to the right of the decimal point.
<idlm>com.sun.star.awt.UnoControlNumericFieldModel:ShowThousandsSeparator</idlm> boolean. Determines whether thousands separators are used.
<idlm>com.sun.star.awt.UnoControlNumericFieldModel:Value</idlm> double. Specifies the current value of the control.
<idlm>com.sun.star.awt.UnoControlNumericFieldModel:ValueMax</idlm> double. Specifies the maximum value that the user can enter.
<idlm>com.sun.star.awt.UnoControlNumericFieldModel:ValueMin</idlm> double. Specifies the minimum value that the user can enter.
<idlm>com.sun.star.awt.UnoControlNumericFieldModel:ValueStep</idlm> double. Specifies the interval steps when using the spin button.

The code example sets up a numeric field with a defined number format and defines the numerical range within which the Value may be modified.

public XPropertySet insertNumericField( int _nPosX, int _nPosY, int _nWidth,
                                        double _fValueMin, double _fValueMax, double _fValue,
                                        double _fValueStep, short _nDecimalAccuracy) {
    XPropertySet xNFModelPSet = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "NumericField");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oNFModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlNumericFieldModel");
        XMultiPropertySet xNFModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oNFModel);
        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xNFModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "PositionX", "PositionY", "Spin", "StrictFormat", "Width"},
        new Object[] { new Integer(12), sName, new Integer(_nPosX), new Integer(_nPosY), Boolean.TRUE, Boolean.TRUE, new Integer(_nWidth)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oNFModel);
        xNFModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oNFModel);
        // The following properties may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        xNFModelPSet.setPropertyValue("ValueMin", new Double(_fValueMin));
        xNFModelPSet.setPropertyValue("ValueMax", new Double(_fValueMax));
        xNFModelPSet.setPropertyValue("Value", new Double(_fValue));
        xNFModelPSet.setPropertyValue("ValueStep", new Double(_fValueStep));
        xNFModelPSet.setPropertyValue("ShowThousandsSeparator", Boolean.TRUE);
        xNFModelPSet.setPropertyValue("DecimalAccuracy", new Short(_nDecimalAccuracy));
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xNFModelPSet;
}

Currency Field

The currency field control <idl>com.sun.star.awt.UnoControlCurrencyField</idl> can be considered a specialization of the <idl>com.sun.star.awt.UnoControlNumericField</idl>. It is used for entering and displaying currency values. In addition to the currency value, reflected by the property Value, a currency symbol, set by the CurrencySymbol property, is displayed. If the PrependCurrencySymbol property is set to true, the currency symbol is displayed in front of the currency value.

public XTextComponent insertCurrencyField(XTextListener _xTextListener, int _nPositionX, int _nPositionY, int _nWidth) {
    XTextComponent xTextComponent = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "CurrencyField");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oCFModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlCurrencyFieldModel");
        XMultiPropertySet xCFModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oCFModel);

        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xCFModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "PositionX", "PositionY", "Width"},
        new Object[] { new Integer(12), sName, new Integer(_nPositionX), new Integer(_nPositionY), new Integer(_nWidth)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oCFModel);
        XPropertySet xCFModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oCFModel);

        // The following properties may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        xCFModelPSet.setPropertyValue("PrependCurrencySymbol", Boolean.TRUE);
        xCFModelPSet.setPropertyValue("CurrencySymbol", "$");
        xCFModelPSet.setPropertyValue("Value", new Double(2.93));

        // add a textlistener that is notified on each change of the controlvalue...
        Object oCFControl = m_xDlgContainer.getControl(sName);
        xTextComponent = (XTextComponent) UnoRuntime.queryInterface(XTextComponent.class, oCFControl);
        xTextComponent.addTextListener(_xTextListener);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xTextComponent;
}

Date Field

The date field control <idl>com.sun.star.awt.UnoControlDateField</idl> extends the text field control and is used for displaying and entering dates. The model is described in <idl>com.sun.star.awt.UnoControlDateFieldModel</idl>:

Properties of <idl>com.sun.star.awt.UnoControlDateFieldModel</idl>
<idlm>com.sun.star.awt.UnoControlDateFieldModel:Date</idlm> long. The date value displayed in the control. The type of the property is long and specified by the number format YYYYMMDD, where YYYY denotes fully qualified years, MM months, and DD days.
<idlm>com.sun.star.awt.UnoControlDateFieldModel:DateFormat</idlm> short. The DateFormat is a key that determines the number format of the displayed date.
<idlm>com.sun.star.awt.UnoControlDateFieldModel:DateMax</idlm> long. The maximum date that the user can enter
<idlm>com.sun.star.awt.UnoControlDateFieldModel:DateMin</idlm> long. The minimum date that the user can enter
<idlm>com.sun.star.awt.UnoControlDateFieldModel:DateShowCentury</idlm> This property is deprecated and should not be used.
<idlm>com.sun.star.awt.UnoControlDateFieldModel:Dropdown</idlm> boolean. The Dropdown property enables a calendar that the user can drop down to select a date.
<idlm>com.sun.star.awt.UnoControlDateFieldModel:Spin</idlm> boolean. The Spin property defines whether the control displays a spin button. This method reduces scrolling and selecting, to a one-step process.
<idlm>com.sun.star.awt.UnoControlDateFieldModel:StrictFormat</idlm> boolean. If set to true, only the allowed characters as specified by the DateFormat property are accepted. All other entries typed with the keyboard are ignored.

public XPropertySet insertDateField(XSpinListener _xSpinListener, int _nPosX, int _nPosY, int _nWidth) {
    XPropertySet xDFModelPSet = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "DateField");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oDFModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlDateFieldModel");
        XMultiPropertySet xDFModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oDFModel);

        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xDFModelMPSet.setPropertyValues(
        new String[] {"Dropdown", "Height", "Name", "PositionX", "PositionY", "Width"},
        new Object[] {Boolean.TRUE, new Integer(12), sName, new Integer(_nPosX), new Integer(_nPosY), new Integer(_nWidth)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oDFModel);
        xDFModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oDFModel);

        // The following properties may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        xDFModelPSet.setPropertyValue("DateFormat", new Short((short) 7));
        xDFModelPSet.setPropertyValue("DateMin", new Integer(20070401));
        xDFModelPSet.setPropertyValue("DateMax", new Integer(20070501));
        xDFModelPSet.setPropertyValue("Date", new Integer(20000415));
        Object oDFControl = m_xDlgContainer.getControl(sName);

        // add a SpinListener that is notified on each change of the controlvalue...
        XSpinField xSpinField = (XSpinField) UnoRuntime.queryInterface(XSpinField.class, oDFControl);
        xSpinField.addSpinListener(_xSpinListener);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xDFModelPSet;
}

Note pin.svg

Note:
Note: LibreOffice Basic developers can use the runtime functions CDateToIso() or CDateFromIso() to convert the date in ISO format from or to a serial date number that is generated by the DateSerial() or the DateValue() function.

Although the date field control provides a spin button, there is no Step property. In this control, the interval steps of the spin button are set automatically and depend on the position of the cursor within the date display. This means that if, for example, the cursor is within the month section of the date display, only the months are controlled by the spin button.

Time Field

The time field control <idl>com.sun.star.awt.UnoControlTimeField</idl> and its model <idl>com.sun.star.awt.UnoControlTimeFieldModel</idl> displays and enters time values.

Properties of <idl>com.sun.star.awt.UnoControlTimeFieldModel</idl>
<idlm>com.sun.star.awt.UnoControlTimeFieldModel:Time</idlm> long. The time value is set and retrieved by the Time property. The time value is of type long and is specified in the ISO format HHMMSShh, where HH are hours, MM are minutes, SS are seconds and hh are hundredth seconds. See the example below.
<idlm>com.sun.star.awt.UnoControlTimeFieldModel:TimeFormat</idlm> short. The format of the displayed time is specified by the TimeFormat key that denotes defined formats as specified below where a Time value of 15182300 is assumed:
Key Description Example
0: 24h short 15:18
1 24h long 15:18:23
2 12h short 03:18PM
3 12h long 03:18:23PM
4 Duration short 15:18
5 Duration long 15:18:23
<idlm>com.sun.star.awt.UnoControlTimeFieldModel:TimeMax</idlm> long. Similar to to the UnoControlDateField, the minimum and maximum time value that can be entered is given by the TimeMin and TimeMax properties. If the value of Time exceeds one of these two limits the value is automatically reset to the according maximum or minimum value.
<idlm>com.sun.star.awt.UnoControlTimeFieldModel:TimeMin</idlm>

Although the time field provides a spin button, there is no Step property. In this control the interval steps are set automatically and depend on the position of the cursor within the time display. For example, if the cursor is within the minute section of the time display only the minutes are controlled by the spin button.

public XPropertySet insertTimeField(int _nPosX, int _nPosY, int _nWidth, int _nTime, int _nTimeMin, int _nTimeMax) {
    XPropertySet xTFModelPSet = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "TimeField");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oTFModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlTimeFieldModel");
        XMultiPropertySet xTFModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oTFModel);

        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xTFModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "PositionX", "PositionY", "Spin", "Width"},
        new Object[] { new Integer(12), sName, new Integer(_nPosX), new Integer(_nPosY), Boolean.TRUE, new Integer(_nWidth)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oTFModel);
        xTFModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oTFModel);

        // The following properties may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        xTFModelPSet.setPropertyValue("TimeFormat", new Short((short) 5));
        xTFModelPSet.setPropertyValue("TimeMin", new Integer(_nTimeMin));
        xTFModelPSet.setPropertyValue("TimeMax", new Integer(_nTimeMax));
        xTFModelPSet.setPropertyValue("Time", new Integer(_nTime));
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xTFModelPSet;
}

Pattern Field

The pattern field control <idl>com.sun.star.awt.UnoControlPatternField</idl> defines a character code that restricts the user input. This character code that determines what the user may enter is defined by the EditMask property. The length of the edit is equivalent to the number of the possible input positions. If a character is entered that does not correspond to the edit mask, the input is rejected. For example, in the edit mask "NNLNNLLLLL" the character "L" has the meaning of a text constant and the character "N" means that only the digits 0 to 9 can be entered. A complete list of valid characters can be found in the table below. The LiteralMask property contains the initial values that are displayed in the pattern field. The length of the literal mask should always correspond to the length of the edit mask. An example of a literal mask which fits to the edit mask would be "__.__.2002". In this case, the user enters only 4 digits when entering a date. If StrictFormat is set to true, the text will be checked during user input. If StrictFormat is not set to true the text is not checked until the focus is leaving the control.

Character of property EditMask Meaning
L A text constant. This position cannot be edited. The character is displayed at the corresponding position of the Literal Mask.
a The characters a-z and A-Z can be entered. Capital characters are not converted to lowercase characters.
A The characters A-Z can be entered. If a lowercase letter is entered, it is automatically converted to a capital letter
c The characters a-z, A-Z, and 0-9 can be entered. Capital characters are not converted to lowercase characters.
C The characters A-Z and 0-9 can be entered. If a lowercase letter is entered, it is automatically converted to a capital letter.
N Only the characters 0-9 can be entered.
x All printable characters can be entered.
X All printable characters can be entered. If a lowercase letter is used, it is automatically converted to a capital letter.

public XPropertySet insertPatternField(int _nPosX, int _nPosY, int _nWidth) {
    XPropertySet xPFModelPSet = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "PatternField");

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oPFModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlPatternFieldModel");
        XMultiPropertySet xPFModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oPFModel);

        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        xPFModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "PositionX", "PositionY", "Width"},
        new Object[] { new Integer(12), sName, new Integer(_nPosX), new Integer(_nPosY), new Integer(_nWidth)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oPFModel);
        xPFModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oPFModel);

        // The following properties may also be set with XMultiPropertySet but we
        // use the XPropertySet interface merely for reasons of demonstration
        xPFModelPSet.setPropertyValue("LiteralMask", "__.05.2007");
        // Allow only numbers for the first two digits...
        xPFModelPSet.setPropertyValue("EditMask", "NNLLLLLLLL");
        // verify the user input immediately...
        xPFModelPSet.setPropertyValue("StrictFormat", Boolean.TRUE);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xPFModelPSet;
}

Roadmap Control

The roadmap control that supports the service <idl>com.sun.star.awt.UnoControlRoadmap</idl> is a container of roadmap items supporting <idl>com.sun.star.awt.RoadmapItem</idl>. The roadmap control was designed to give an overview about all existing steps in a dialog as done in all LibreOffice wizards. The roadmap items are labels with some additional functionality as described later in the text. They are due to give the user a clue about "what is going on" on a certain dialog step. Roadmap items can be programmatically accessed by their respective index using the interface <idls>com.sun.star.container.XIndexContainer</idls> at the roadmap model that is described by <idl>com.sun.star.awt.UnoControlRoadmapModel</idl>.

Roadmap Item

Each roadmap item delivers the following information:

Properties of <idl>com.sun.star.awt.RoadmapItem</idl>
<idlm>com.sun.star.awt.RoadmapItem:ID</idlm> short. The ID uniquely identifies the roadmap item and can be used to refer to the value of a dialog step.
<idlm>com.sun.star.awt.RoadmapItem:Label</idlm> The label of a roadmap item is displayed similar to the label of a fixed text control. Each label is prefixed with an index and a ". ".
<idlm>com.sun.star.awt.RoadmapItem:Interactive</idlm> boolean. Setting Interactive to true will automatically change the mouse pointer to a refhand and underline the label for the time the mouse pointer resides over the roadmap item. Clicking the mouse pointer will then notify the roadmap container. The property Interactive is readonly because it is adapted from the container of the roadmap item, the roadmap model. When the user clicks on the roadmap item of an interactive roadmap the ID of the triggered roadmap item automatically gets selected - similarly to the selection of a list box item. Automatically the property CurrentItemID of the roadmap model is set to the value of the property ID of the roadmap item element.
<idlm>com.sun.star.awt.RoadmapItem:Enabled</idlm> boolean. Determines whether a roadmap item is enabled or disabled. As roadmap items usually refer to a dialog step they are disabled when the the actions taking place on that step have become unnecessary for example because of user input.
Roadmap Controlmodel
Properties of <idl>com.sun.star.awt.UnoControlRoadmapModel</idl>
<idlm>com.sun.star.awt.UnoControlRoadmapModel:BackgroundColor</idlm> long. Specifies the background color (RGB) of the control. The Default value is white.
<idlm>com.sun.star.awt.UnoControlRoadmapModel:Interactive</idlm> boolean. Determines whether the roadmap items are interactive or not. To have an interactive roadmap may demand some extra implementation work because the developer will then be responsible to check if for each roadmap item the necessary prerequisites are fulfilled to allow the user to enter the respective dialog step.
<idlm>com.sun.star.awt.UnoControlRoadmapModel:Complete</idlm> boolean. Determines whether the control container is complete or not. It might occur that the exact roadmap of an assistant is not clear from the beginning because it contains one or several branches where the input of the user impacts the content of the roadmap. If it is unclear how the roadmap is moving on after a branch the following step after the branch is visualized with "". In this case the property Complete is previously set to false. The steps afterwards are unavailable as long as the state of this branch is uncertain.
<idlm>com.sun.star.awt.UnoControlRoadmapModel:ImageURL</idlm> string. Refers to an image that is displayed in the bottom right corner of the roadmap. The image is meant to contain a metaphor that can easily be associated with the task of the wizard or the subtask of an according step.
<idlm>com.sun.star.awt.UnoControlRoadmapModel:Text</idlm> string. Specifies the bold and underlined text displayed in the top of the control
<idlm>com.sun.star.awt.UnoControlRoadmapModel:CurrentItemID</idlm> short. Refers to the ID of the currently selected roadmap item. Initially this property is set to '-1' which is equal to 'undefined.
Roadmap

Specifies a Roadmap control. A roadmap implements the interface <idl>com.sun.star.awt.XItemEventBroadcaster</idl>, which is helpful to add an ItemListener to the roadmap, when the property Interactive of the roadmap model is set to true. The listener is then always notified about changes of the property CurrentItemID and has an opportunity to adjust the property Step of the dialog.

The following example listings are supposed to give an idea how a roadmap can be used to control the displayed steps of a dialog:

// Globally available object variables of the roadmapmodel
XPropertySet m_xRMPSet;
XSingleServiceFactory m_xSSFRoadmap;
XIndexContainer m_xRMIndexCont;

public void addRoadmap(XItemListener _xItemListener) {
    try {
        // create a unique name by means of an own implementation...
        String sRoadmapName = createUniqueName(m_xDlgModelNameContainer, "Roadmap");

        XPropertySet xDialogModelPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, m_xMSFDialogModel);
        // Similar to the office assistants the roadmap is adjusted to the height of the dialog
        // where a certain space is left at the bottom for the buttons...
        int nDialogHeight = ((Integer) xDialogModelPropertySet.getPropertyValue("Height")).intValue();

        // instantiate the roadmapmodel...
        Object oRoadmapModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlRoadmapModel");

        // define the properties of the roadmapmodel
        XMultiPropertySet xRMMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oRoadmapModel);
        xRMMPSet.setPropertyValues( new String[] {"Complete", "Height", "Name", "PositionX", "PositionY", "Text", "Width" },
        new Object[] {Boolean.FALSE, new Integer(nDialogHeight - 26), sRoadmapName, new Integer(0), new Integer(0), "Steps", new Integer(85)});
        m_xRMPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oRoadmapModel);

        // add the roadmapmodel to the dialog container..
        m_xDlgModelNameContainer.insertByName(sRoadmapName, oRoadmapModel);

        // the roadmapmodel is a SingleServiceFactory to instantiate the roadmapitems...
        m_xSSFRoadmap = (XSingleServiceFactory) UnoRuntime.queryInterface(XSingleServiceFactory.class, oRoadmapModel);
        m_xRMIndexCont = (XIndexContainer) UnoRuntime.queryInterface(XIndexContainer.class, oRoadmapModel);

        // add the itemlistener to the control...
        XControl xRMControl = this.m_xDlgContainer.getControl(sRoadmapName);
        XItemEventBroadcaster xRMBroadcaster = (XItemEventBroadcaster) UnoRuntime.queryInterface(XItemEventBroadcaster.class, xRMControl);
        xRMBroadcaster.addItemListener(new RoadmapItemStateChangeListener()); //_xItemListener);
    } catch (java.lang.Exception jexception) {
        jexception.printStackTrace(System.out);
    }
}

The following code snippet inserts a roadmap item into the roadmap control model.

/**
* To fully understand the example one has to be aware that the passed "Index" parameter
* refers to the position of the roadmap item in the roadmapmodel container
* whereas the variable "_ID" directly references to a certain step of dialog.
*/
public void insertRoadmapItem(int Index, boolean _bEnabled, String _sLabel, int _ID) {
    try {
        // a roadmap is a SingleServiceFactory that can only create roadmapitems that are the only possible
        // element types of the container
        Object oRoadmapItem = m_xSSFRoadmap.createInstance();
        XPropertySet xRMItemPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class,       oRoadmapItem);
        xRMItemPSet.setPropertyValue("Label", _sLabel);
        // sometimes steps are supposed to be set disabled depending on the program logic...
        xRMItemPSet.setPropertyValue("Enabled", new Boolean(_bEnabled));
        // in this context the "ID" is meant to refer to a step of the dialog
        xRMItemPSet.setPropertyValue("ID", new Integer(_ID));
        m_xRMIndexCont.insertByIndex(Index, oRoadmapItem);
    } catch (com.sun.star.uno.Exception exception) {
        exception.printStackTrace(System.out);
    }
}

The following example demonstrates the way an ItemListener could evaluate the information of the roadmap control to adjust the step of the dialog:

public void itemStateChanged(com.sun.star.awt.ItemEvent itemEvent) {
    try {
        // get the new ID of the roadmap that is supposed to refer to the new step of the dialogmodel
        int nNewID = itemEvent.ItemId;
        XPropertySet xDialogModelPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, m_xMSFDialogModel);
        int nOldStep = ((Integer) xDialogModelPropertySet.getPropertyValue("Step")).intValue();
        // in the following line "ID" and "Step" are mixed together.
        // In fact in this case they denot the same
        if (nNewID != nOldStep) {
            xDialogModelPropertySet.setPropertyValue("Step", new Integer(nNewID));
        }
    } catch (com.sun.star.uno.Exception exception) {
        exception.printStackTrace(System.out);
    }
}

File Control

The file control supports the service <idl>com.sun.star.awt.UnoControlFileControl</idl> and covers a lot of the functionality of an UnoControlEdit control and a command button that is built in the control. This is put into practice by a control supporting the service <idl>com.sun.star.awt.UnoControlEdit</idl>. Similar to a Text Field the content may be retrieved by a Text property. The value of Text denotes the path of the control. Clicking this button brings up a file dialog in which the user may select a file that is taken over by by the file control like a text field. The following example sets up a file control. It is initialized with the configured Workpath of the office installation that is converted to a system path before passed to the Text property of the control Path Settings.

public XTextComponent insertFileControl(XTextListener _xTextListener, int _nPosX, int _nPosY, int _nWidth) {
    XTextComponent xTextComponent = null;
    try {
        // create a unique name by means of an own implementation...
        String sName = createUniqueName(m_xDlgModelNameContainer, "FileControl");

        // retrieve the configured Work path...
        Object oPathSettings = m_xMCF.createInstanceWithContext("com.sun.star.util.PathSettings",m_xContext);
        XPropertySet xPropertySet = (XPropertySet) com.sun.star.uno.UnoRuntime.queryInterface(XPropertySet.class, oPathSettings);
        String sWorkUrl = (String) xPropertySet.getPropertyValue("Work");

        // convert the Url to a system path that is "human readable"...
        Object oFCProvider = m_xMCF.createInstanceWithContext("com.sun.star.ucb.FileContentProvider", m_xContext);
        XFileIdentifierConverter xFileIdentifierConverter = (XFileIdentifierConverter) UnoRuntime.queryInterface(XFileIdentifierConverter.class, oFCProvider);
        String sSystemWorkPath = xFileIdentifierConverter.getSystemPathFromFileURL(sWorkUrl);

        // create a controlmodel at the multiservicefactory of the dialog model...
        Object oFCModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlFileControlModel");

        // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
        XMultiPropertySet xFCModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oFCModel);
        xFCModelMPSet.setPropertyValues(
        new String[] {"Height", "Name", "PositionX", "PositionY", "Text", "Width"},
        new Object[] { new Integer(12), sName, new Integer(_nPosX), new Integer(_nPosY), sSystemWorkPath, new Integer(_nWidth)});

        // The controlmodel is not really available until inserted to the Dialog container
        m_xDlgModelNameContainer.insertByName(sName, oFCModel);
        XPropertySet xFCModelPSet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, oFCModel);

        // add a textlistener that is notified on each change of the controlvalue...
        XControl xFCControl = m_xDlgContainer.getControl(sName);
        xTextComponent = (XTextComponent) UnoRuntime.queryInterface(XTextComponent.class, xFCControl);
        XWindow xFCWindow = (XWindow) UnoRuntime.queryInterface(XWindow.class, xFCControl);
        xTextComponent.addTextListener(_xTextListener);
    } catch (com.sun.star.uno.Exception ex) {
        /* perform individual exception handling here.
        * Possible exception types are:
        * com.sun.star.lang.IllegalArgumentException,
        * com.sun.star.lang.WrappedTargetException,
        * com.sun.star.container.ElementExistException,
        * com.sun.star.beans.PropertyVetoException,
        * com.sun.star.beans.UnknownPropertyException,
        * com.sun.star.uno.Exception
        */
        ex.printStackTrace(System.out);
    }
    return xTextComponent;
}

The file control also allows the configuration of the file dialog. File dialogs implementing the service <idl>com.sun.star.ui.dialogs.FilePicker</idl> do not belong to the module <idlmodule>com.sun.star.awt</idlmodule>, but, as they are frequently used by extension developers, this topic shall also be covered in this chapter.

Currently the control does not yet offer the described complete functionality which is addressed by https://www.openoffice.org/issues/show_bug.cgi?id=71041.

File Picker

A file picker supports the service <idl>com.sun.star.ui.dialogs.FilePicker</idl> and may depict a file-open or a file-save dialog in all conceivable facets. LibreOffice supports a great variety of filters. These may be applied to the file picker by means of the filter manager. Filters also affect the list of files displayed by the dialog and enable the file picker to append the file extension automatically. The names of the filters and their titles may be queried programmatically from the LibreOffice registry or - much easier like in the coding example below - be retrieved from Framework/Article/Filter. The following listing illustrates how to customize and raise a file-save dialog and query the result afterwards. The result is a file URL pointing to the location where a file is to be stored.

public String raiseSaveAsDialog() {
String sStorePath = "";
XComponent xComponent = null;
    try {
        // the filepicker is instantiated with the global Multicomponentfactory...
        Object oFilePicker = m_xMCF.createInstanceWithContext("com.sun.star.ui.dialogs.FilePicker", m_xContext);
        XFilePicker xFilePicker = (XFilePicker) UnoRuntime.queryInterface(XFilePicker.class, oFilePicker);

        // the defaultname is the initially proposed filename..
        xFilePicker.setDefaultName("MyExampleDocument");

        // set the initial displaydirectory. In this example the user template directory is used
        Object oPathSettings = m_xMCF.createInstanceWithContext("com.sun.star.util.PathSettings",m_xContext);
        XPropertySet xPropertySet = (XPropertySet) com.sun.star.uno.UnoRuntime.queryInterface(XPropertySet.class, oPathSettings);
        String sTemplateUrl = (String) xPropertySet.getPropertyValue("Template_writable");
        xFilePicker.setDisplayDirectory(sTemplateUrl);

        // set the filters of the dialog. The filternames may be retrieved from
        // http://wiki.services.openoffice.org/wiki/Framework/Article/Filter
        XFilterManager xFilterManager = (XFilterManager) UnoRuntime.queryInterface(XFilterManager.class, xFilePicker);
        xFilterManager.appendFilter("OpenDocument Text Template", "writer8_template");
        xFilterManager.appendFilter("OpenDocument Text", "writer8");

        // choose the template that defines the capabilities of the filepicker dialog
        XInitialization xInitialize = (XInitialization) UnoRuntime.queryInterface(XInitialization.class, xFilePicker);
        Short[] listAny = new Short[] { new Short(com.sun.star.ui.dialogs.TemplateDescription.FILESAVE_AUTOEXTENSION)};
        xInitialize.initialize(listAny);

        // add a control to the dialog to add the extension automatically to the filename...
        XFilePickerControlAccess xFilePickerControlAccess = (XFilePickerControlAccess) UnoRuntime.queryInterface(XFilePickerControlAccess.class, xFilePicker);
        xFilePickerControlAccess.setValue(com.sun.star.ui.dialogs.ExtendedFilePickerElementIds.CHECKBOX_AUTOEXTENSION, (short) 0, new Boolean(true));

        xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, xFilePicker);

        // execute the dialog...
        XExecutableDialog xExecutable = (XExecutableDialog) UnoRuntime.queryInterface(XExecutableDialog.class, xFilePicker);
        short nResult = xExecutable.execute();

        // query the resulting path of the dialog...
        if (nResult == com.sun.star.ui.dialogs.ExecutableDialogResults.OK) {
            String[] sPathList = xFilePicker.getFiles();
            if (sPathList.length > 0) {
                sStorePath = sPathList[0];
            }
        }

    } catch (com.sun.star.uno.Exception exception) {
        exception.printStackTrace();
    }
    finally {
        //make sure always to dispose the component and free the memory!
        if (xComponent != null) {
            xComponent.dispose();
        }
    }

    return sStorePath;
}

The directory that the file dialog initially displays is set by the setDisplayDirectory() method. Of course, it must be set as a file URL. If no directory is passed, the customized Work-directory of the office application is shown.

Next to the file picker service it is also possible to raise a folder picker implementing the service <idl>com.sun.star.ui.dialogs.FolderPicker</idl>. Unlike the file picker the folder picker only displays folders.

/** raises a folderpicker in which the user can browse and select a path
* @param _sDisplayDirectory the path to the directory that is initially displayed
* @param _sTitle the title of the folderpicker
* @return the path to the folder that the user has selected. if the user has closed
* the folderpicker by clicking the "Cancel" button
* an empty string is returned
* @see com.sun.star.ui.dialogs.FolderPicker
*/
public String raiseFolderPicker(String _sDisplayDirectory, String _sTitle) {
String sReturnFolder = "";
XComponent xComponent = null;
    try {
        // instantiate the folder picker and retrieve the necessary interfaces...
        Object oFolderPicker = m_xMCF.createInstanceWithContext("com.sun.star.ui.dialogs.FolderPicker", m_xContext);
        XFolderPicker xFolderPicker = (XFolderPicker) UnoRuntime.queryInterface(XFolderPicker.class, oFolderPicker);
        XExecutableDialog xExecutable = (XExecutableDialog) UnoRuntime.queryInterface(XExecutableDialog.class, oFolderPicker);
        xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, oFolderPicker);
        xFolderPicker.setDisplayDirectory(_sDisplayDirectory);
        // set the dialog title...
        xFolderPicker.setTitle(_sTitle);
        // show the dialog...
        short nResult = xExecutable.execute();

        // User has clicked "Select" button...
        if (nResult == com.sun.star.ui.dialogs.ExecutableDialogResults.OK) {
            sReturnFolder = xFolderPicker.getDirectory();
        }

    } catch( Exception exception ) {
        exception.printStackTrace(System.out);
    }
    finally {
        //make sure always to dispose the component and free the memory!
        if (xComponent != null) {
            xComponent.dispose();
        }
    }
    // return the selected path. If the user has clicked cancel an empty string is
    return sReturnFolder;
}

Message Box

Message boxes contain a defined message and title that may be combined with predefined icons and buttons. Again the central instance to create a Message box is the service <idl>com.sun.star.awt.Toolkit</idl>. It serves as a factory that exports the interface <idl>com.sun.star.awt.XMessageBoxFactory</idl>. Its method createMessageBox() allows the creation of message boxes in various defined facets.

  • The first parameter of createMessageBox() denotes the peer of the parent window. In analogy to all LibreOffice windows the peer of the window parent must be conveyed.
  • The second parameter aPosSize may be empty (but not null).
  • The third parameter aType describes the special usecase of the message box. The interface description lists a bunch of defined strings like "errorbox" or "querybox". The message box type is than differentiated by its contained icon.
  • Depending on the use case, different combinations of buttons in the message box are possible and reflected by a value of the constants group <idl>com.sun.star.awt.MessageBoxButtons</idl>. This is the fourth parameter aButtons.
  • The last two parameters reflect the title (aTitle) and the message (aMessage) of the message box.

This example creates and executes a message box.

/** shows an error messagebox
* @param _xParentWindowPeer the windowpeer of the parent window
* @param _sTitle the title of the messagebox
* @param _sMessage the message of the messagebox
*/
public void showErrorMessageBox(XWindowPeer _xParentWindowPeer, String _sTitle, String _sMessage) {
XComponent xComponent = null;
    try {
        Object oToolkit = m_xMCF.createInstanceWithContext("com.sun.star.awt.Toolkit", m_xContext);
        XMessageBoxFactory xMessageBoxFactory = (XMessageBoxFactory) UnoRuntime.queryInterface(XMessageBoxFactory.class, oToolkit);
        // rectangle may be empty if position is in the center of the parent peer
        Rectangle aRectangle = new Rectangle();
        XMessageBox xMessageBox = xMessageBoxFactory.createMessageBox(_xParentWindowPeer, aRectangle, "errorbox", com.sun.star.awt.MessageBoxButtons.BUTTONS_OK, _sTitle, _sMessage);
        xComponent = (XComponent) UnoRuntime.queryInterface(XComponent.class, xMessageBox);
        if (xMessageBox != null) {
            short nResult = xMessageBox.execute();
        }
    } catch (com.sun.star.uno.Exception ex) {
        ex.printStackTrace(System.out);
    }
    finally {
        //make sure always to dispose the component and free the memory!
        if (xComponent != null) {
            xComponent.dispose();
        }
    }
}

The Toolkit Service

The Service <idl>com.sun.star.awt.Toolkit</idl> is the central instance to create Windows. For this purpose the interface <idl>com.sun.star.awt.XToolkit</idl> is of major interest. The two methods getDesktopWindow() and getWorkArea() were used when LibreOffice offered an intregrated DesktopWindow, and are now deprecated. An instance of the <idl>com.sun.star.awt.Toolkit</idl> is created at the global MultiServicefactory. One way to get this peer from the frame of the document window can be seen in the following example.

Before investigating this example, it is reasonable to briefly describe the character of a frame. A frame exports the interface <idl>com.sun.star.frame.XFrame</idl> and serves as a container for arbitrary content - mostly document models. To visualize this content it uses a window (<idl>com.sun.star.awt.XWindow</idl>). It is the central coordination instance that brings together menus, documents, LayoutManager (see <idl>com.sun.star.frame.XLayoutManager</idl>) and progress bars. For more information see Using the Component Framework. Another important responsibility is the delivery of commands - for example commands fired from toolbar buttons - to the components. See Dispatch Framework and Using the Dispatch Framework for more information on this. A frame may be embedded in a hierarchy of other frames. The following example demonstrates the creation of a very basic window that is attached to a desktop frame.

public XTopWindow showTopWindow( Rectangle _aRectangle) {
    XTopWindow xTopWindow = null;
    try {
        // The Toolkit is the creator of all windows...
        Object oToolkit = m_xMCF.createInstanceWithContext("com.sun.star.awt.Toolkit", m_xContext);
        XToolkit xToolkit = (XToolkit) UnoRuntime.queryInterface(XToolkit.class, oToolkit);

        // set up a window description and create the window. A parent window is always necessary for this...
        com.sun.star.awt.WindowDescriptor aWindowDescriptor = new com.sun.star.awt.WindowDescriptor();
        // a TopWindow is contains a title bar and is able to inlude menus...
        aWindowDescriptor.Type = WindowClass.TOP;
        // specify the position and height of the window on the parent window
        aWindowDescriptor.Bounds = _aRectangle;
        // set the window attributes...
        aWindowDescriptor.WindowAttributes = WindowAttribute.SHOW + WindowAttribute.MOVEABLE + WindowAttribute.SIZEABLE + WindowAttribute.CLOSEABLE;

        // create the window...
        XWindowPeer xWindowPeer = xToolkit.createWindow(aWindowDescriptor);
        XWindow xWindow = (XWindow) UnoRuntime.queryInterface(XWindow.class, xWindowPeer);

        // create a frame and initialize it with the created window...
        Object oFrame = m_xMCF.createInstanceWithContext("com.sun.star.frame.Frame", m_xContext);
        m_xFrame = (XFrame) UnoRuntime.queryInterface(XFrame.class, oFrame);

        Object oDesktop = m_xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", m_xContext);
        XFramesSupplier xFramesSupplier = (XFramesSupplier) UnoRuntime.queryInterface(XFramesSupplier.class, oDesktop);
        m_xFrame.setCreator(xFramesSupplier);
        // get the XTopWindow interface..
        xTopWindow = (XTopWindow) UnoRuntime.queryInterface(XTopWindow.class, xWindow);
    } catch (com.sun.star.lang.IllegalArgumentException ex) {
        ex.printStackTrace();
    } catch (com.sun.star.uno.Exception ex) {
        ex.printStackTrace();
    }
    return xTopWindow;
}

As can be seen, the window is described by a <idl>com.sun.star.awt.WindowDescriptor</idl> that manifests all the facets of the window and also the window attributes as defined in <idl>com.sun.star.awt.WindowAttribute</idl>. It is possible, but not necessary, to define a parent window. The member Type of the windowdescriptor distinguishes between various values of the enumeration <idl>com.sun.star.awt.WindowClass</idl>.

Values of <idl>com.sun.star.awt.WindowClass</idl>
<idlm>com.sun.star.awt.WindowClass:TOP</idlm> Specifies if a window is a TopWindow with the ability to include a menubar and a titlebar.
<idlm>com.sun.star.awt.WindowClass:MODALTOP</idlm> Specifies if a window is a modal TopWindow that imperatively waits for user input.
<idlm>com.sun.star.awt.WindowClass:CONTAINER</idlm> Specifies if a window may include child windows.
<idlm>com.sun.star.awt.WindowClass:SIMPLE</idlm> A simple window that may also be a container.

The following example shows how a document is loaded into a window that has been previously inserted into a dialog. The example method expects the peer of the parent dialog to be passed over.

public void showDocumentinDialogWindow(XWindowPeer _xParentWindowPeer, Rectangle _aRectangle, String _sUrl) {
    try {
        // The Toolkit is the creator of all windows...
        Object oToolkit = m_xMCF.createInstanceWithContext("com.sun.star.awt.Toolkit", m_xContext);
        XToolkit xToolkit = (XToolkit) UnoRuntime.queryInterface(XToolkit.class, oToolkit);

        // set up a window description and create the window. A parent window is always necessary for this...
        com.sun.star.awt.WindowDescriptor aWindowDescriptor = new com.sun.star.awt.WindowDescriptor();
        // a simple window is enough for this purpose...
        aWindowDescriptor.Type = WindowClass.SIMPLE;
        aWindowDescriptor.WindowServiceName = "dockingwindow";
        // assign the parent window peer as described in the idl description...
        aWindowDescriptor.Parent = _xParentWindowPeer;
        aWindowDescriptor.ParentIndex = 1;
        aWindowDescriptor.Bounds = _aRectangle;

        // set the window attributes...
        // The attribute CLIPCHILDREN causes the parent to not repaint the areas of the children...
        aWindowDescriptor.WindowAttributes = VclWindowPeerAttribute.CLIPCHILDREN + WindowAttribute.BORDER + WindowAttribute.SHOW;
        XWindowPeer xWindowPeer = xToolkit.createWindow(aWindowDescriptor);
        XWindow xWindow = (XWindow) UnoRuntime.queryInterface(XWindow.class, xWindowPeer);
        XView xView = (XView) UnoRuntime.queryInterface(XView.class, xWindow);

        // create a frame and initialize it with the created window...
        Object oFrame = m_xMCF.createInstanceWithContext("com.sun.star.frame.Frame", m_xContext);
        // The frame should be of global scope because it's within the responsibility to dispose it after usage
        m_xFrame = (XFrame) UnoRuntime.queryInterface(XFrame.class, oFrame);
        m_xFrame.initialize(xWindow);

        // load the document and open it in preview mode
        XComponentLoader xComponentLoader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, m_xFrame);
        PropertyValue[] aPropertyValues = new PropertyValue[2];
        PropertyValue aPropertyValue = new PropertyValue();
        aPropertyValue.Name = "Preview";
        aPropertyValue.Value = Boolean.TRUE;
        aPropertyValues[0] = aPropertyValue;
        aPropertyValue = new PropertyValue();
        aPropertyValue.Name = "ReadOnly";
        aPropertyValue.Value = Boolean.TRUE;
        aPropertyValues[1] = aPropertyValue;
        xComponentLoader.loadComponentFromURL(_sUrl, "_self", 0, aPropertyValues);
    } catch (com.sun.star.lang.IllegalArgumentException ex) {
        ex.printStackTrace();
        throw new java.lang.RuntimeException("cannot happen...");
    } catch (com.sun.star.uno.Exception ex) {
        ex.printStackTrace();
        throw new java.lang.RuntimeException("cannot happen...");
    }
}

As can be seen, the procedure to create the window and its frame is quite straightforward. The example clarifies the role of the frame as the central instance to bring together the window, layout manager and the document (model). You must set the windowAttribute VclWindowPeerAttribute.CLIPCHILDREN to make sure that the graphical operations on the parent window do not interfere with child windows.

Of course, there are use cases where no parent windowpeer is directly available, so this must be retrieved from a frame beforehand.

From the following example you can learn how to get the windowpeer from a frame

/** gets the WindowPeer of a frame
* @param _xFrame the UNO Frame
* @return the windowpeer of the frame
*/
public XWindowPeer getWindowPeer(XFrame _xFrame) {
    XWindow xWindow = _xFrame.getContainerWindow();
    XWindowPeer xWindowPeer = (XWindowPeer) UnoRuntime.queryInterface(XWindowPeer.class, xWindow);
    return xWindowPeer;
}

The ComponentWindow is the window that displays just the view of a document. The Containerwindow is the complete window including its title bar and border.

There are several ways to retrieve a frame. The easiest way to retrieve a frame is to query the frame that has the focus:

public XFrame getCurrentFrame() {
    XFrame xRetFrame = null;
    try {
        Object oDesktop = m_xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", m_xContext);
        XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, oDesktop);
        xRetFrame = xDesktop.getCurrentFrame();
    } catch (com.sun.star.uno.Exception ex) {
        ex.printStackTrace();
    }
    return xRetFrame;
}

This should only be used for debugging purposes. The method getCurrentFrame is based on the implementation of the window handler of the operating system and you cannot be sure that the returned frame is always the desired one on all supported platforms, or that a valid frame is returned at all. Usually each LibreOffice extension provides a frame as explained in Integrating Components into LibreOffice.

Dockable Windows

The interface <idls>com.sun.star.awt.XDockableWindow</idls> is currently unpublished and only used internally to control layout manager based tool bars. Although the interface is exported by Windows too, its method is not fully supported. It is planed to support dockable windows in a future version of LibreOffice.

Creating Menus

If the developer wants to add menus to the LibreOffice menu bar these should be added according the detailed description of the OpenOffice.org Wiki article Implementing an extended recent file popup menu controller.

Add-ons can use the menu bar integration of the add-on feature. More information can be found in Add-Ons.

Programmatic insertion of menus to a menu bar is possible for all windows that support the interface <idl>com.sun.star.awt.XTopWindow</idl>.

Unlike in Java, in LibreOffice the term "PopupMenu" is used for all menus that can be either be used as location independent context menus or "ordinary" menus that are added to a menu bar.

The following example shows that:

  • Menus are created at the global service manager.
  • Following the definition of the constants group <idl>com.sun.star.awt.MenuItemStyle</idl> menu items may either work like radio buttons, check boxes or ordinary menu items. The constant AUTOCHECK changes the behavior of the menu in such a way that the menu item gets checked on its selection.
  • The first parameter nItemId of the method insertItem denotes an identifier of a menu item. This must be a unique identifier if you want to recognize a selected menu item unambiguously. The last parameter nPos denotes the position of the menu item in the menu. The unique identifier is ignored for non-selectable menu items. For all other menu items the identifier must always be unique.
  • "Radio-menuitems" are identified as a group by their positions within the menu, meaning that consecutive "radio - menuitems" automatically belong to the same radio button - group.
  • There is no Object representation for the menu items. After their creation, menu items are accessed by their ItemID within the menu.
  • To assign a shortcut key to a menu item, the tilde "~" prefixes the corresponding character of the menu text.

public XPopupMenu getPopupMenu() {
    XPopupMenu xPopupMenu = null;
    try {
        // create a popup menu
        Object oPopupMenu = m_xMCF.createInstanceWithContext("stardiv.Toolkit.VCLXPopupMenu", m_xContext);
        xPopupMenu = (XPopupMenu) UnoRuntime.queryInterface(XPopupMenu.class, oPopupMenu);
        XMenuExtended xMenuExtended = (XMenuExtended) UnoRuntime.queryInterface(XMenuExtended.class, xPopupMenu);

        xPopupMenu.insertItem((short) 0, "~First Entry", MenuItemStyle.AUTOCHECK, (short) 0);
        xPopupMenu.insertItem((short) 1, "~First Radio Entry", (short) (MenuItemStyle.RADIOCHECK + MenuItemStyle.AUTOCHECK), (short) 1);
        xPopupMenu.insertItem((short) 2, "~Second Radio Entry", (short) (MenuItemStyle.RADIOCHECK + MenuItemStyle.AUTOCHECK), (short) 2);
        xPopupMenu.insertItem((short) 3, "~Third RadioEntry",(short) (MenuItemStyle.RADIOCHECK + MenuItemStyle.AUTOCHECK), (short) 3);
        xPopupMenu.insertSeparator((short)4);
        xPopupMenu.insertItem((short) 4, "F~ifth Entry", (short) (MenuItemStyle.CHECKABLE + MenuItemStyle.AUTOCHECK), (short) 5);
        xPopupMenu.insertItem((short) 5, "~Fourth Entry", (short) (MenuItemStyle.CHECKABLE + MenuItemStyle.AUTOCHECK), (short) 6);
        xPopupMenu.enableItem((short) 1, false);
        xPopupMenu.insertItem((short) 6, "~Sixth Entry", (short) 0, (short) 7);
        xPopupMenu.insertItem((short) 7, "~EightEntry", (short) (MenuItemStyle.RADIOCHECK + MenuItemStyle.AUTOCHECK), (short) 8);
        xPopupMenu.checkItem((short) 2, true);
        xPopupMenu.addMenuListener(this);
    } catch( Exception e ) {
        throw new java.lang.RuntimeException("cannot happen...");
    }
    return xPopupMenu;
}

Issue https://qa.openoffice.org/issues/show_bug.cgi?id=76363 addressed the deprecated notation of the service "stardiv.Toolkit.VCLXPopupMenu"

The added XMenuListener of the menu has to implement several methods such as

  • select - invoked when the menu item is activated
  • highlight - invoked when the menu item is highlighted, for example when the mouse moves over it
  • activate/deactivate - depending on the context, menu items may be activated (enabled) or deactivated (disabled)

All these methods carry a <idl>com.sun.star.awt.MenuEvent</idl> parameter. The menu item at which the method has been triggered can be identified by the MenuId of this struct.

public void select(MenuEvent menuEvent) {
    // find out which menu item has been triggered,
    // by getting the menu-id...
    switch (menuEvent.MenuId) {
        case 0:
            // add your menu-item-specific code here:
            break;
        case 1:
            // add your menu-item-specific code here:
            break;
        default:
            //..
    }
}

public void highlight(MenuEvent menuEvent) {
}

public void deactivate(MenuEvent menuEvent) {
}

public void activate(MenuEvent menuEvent) {
}

As we see, we encounter the Id again that helps us to identify the triggered menu item.

At last the create menu has to be added to a menu bar: As can be seen from the idl description of <idl>com.sun.star.awt.XMenuBar</idl>, it is a direct descendant of <idl>com.sun.star.awt.XMenu</idl>. The menus below the menu bar items are added by means of the method setPopupMenu.

public void addMenuBar(XTopWindow _xTopWindow, XMenuListener _xMenuListener) {
    try {
        // create a menubar at the global MultiComponentFactory...
        Object oMenuBar = m_xMCF.createInstanceWithContext("stardiv.Toolkit.VCLXMenuBar", m_xContext);
        // add the menu items...
        XMenuBar xMenuBar = (XMenuBar) UnoRuntime.queryInterface(XMenuBar.class, oMenuBar);
        xMenuBar.insertItem((short) 0, "~First MenuBar Item", com.sun.star.awt.MenuItemStyle.AUTOCHECK, (short) 0);
        xMenuBar.insertItem((short) 1, "~Second MenuBar Item", com.sun.star.awt.MenuItemStyle.AUTOCHECK, (short) 1);
        xMenuBar.setPopupMenu((short) 0, getPopupMenu());
        xMenuBar.addMenuListener(_xMenuListener);
        _xTopWindow.setMenuBar(xMenuBar);
    } catch( Exception e ) {
        throw new java.lang.RuntimeException("cannot happen...");
    }
}

Accessibility

Certainly for many LibreOffice extension developers, accessibility is an important issue. Luckily all UNO-AWT-elements automatically bring support for various accessibility aspects like keyboard navigation, scheming, assistive technology (AT), and much more, so that the developer does not even have to worry accessibility. A good introduction to this topic is the Wiki article at Accessibility. Some problems may arise and shall be dealt with in this chapter.

In the following scenario, a command button is inserted into a dialog. The label ">" of the button indicates that the activation of the button shifts some data from the left side to the right. As this label cannot be interpreted by the screenreader, an "AccessibleName" must be set at the control. Unfortunately this is not yet possible due to the issue https://www.openoffice.org/issues/show_bug.cgi?id=70296. At this stage, only a temporary solution can be offered that uses the deprecated interface <idl>com.sun.star.awt.XVclWindowPeer</idl>

/** sets the AccessibilityName at a control
* @param _xControl the control that the AccessibilityName is to be assigned to
* @param _sAccessibilityName the AccessibilityName
*/
public void setAccessibleName(XControl _xControl, String _sAccessibilityName) {
    XVclWindowPeer xVclWindowPeer = (XVclWindowPeer) UnoRuntime.queryInterface(XVclWindowPeer.class, _xControl.getPeer());
    xVclWindowPeer.setProperty(""AccessibilityName"", "MyAccessibleName");
}

LibreOffice offers a high contrast mode, in which objects are displayed without fill colors or text colors. This mode will automatically be used when high contrast is chosen in the system settings. Extension developers with the demand to create accessible applications must consider this and provide High-Contrast images for their dialog controls. Also for this usecase, only a temporary solution based on the deprecated interface <idl>com.sun.star.awt.XVclWindowPeer</idl> can be offered:

/**
* @param _xVclWindowPeer the windowpeer of a dialog control or the dialog itself
* @return true if HighContrastMode is activated or false if HighContrastMode is deactivated
*/
public boolean isHighContrastModeActivated(XVclWindowPeer _xVclWindowPeer) {
    boolean bIsActivated = false;
    try {
        if (_xVclWindowPeer != null) {
            int nUIColor = AnyConverter.toInt(_xVclWindowPeer.getProperty("DisplayBackgroundColor"));
            int nRed = getRedColorShare(nUIColor);
            int nGreen = getGreenColorShare(nUIColor);
            int nBlue = getBlueColorShare(nUIColor);
            int nLuminance = (( nBlue*28 + nGreen*151 + nRed*77 ) / 256 );
            boolean bisactivated = (nLuminance <= 25);
            return bisactivated;
        }
        else{
            return false;
        }
    } catch (IllegalArgumentException e) {
        e.printStackTrace(System.out);
    }
    return bIsActivated;
}

public static int getRedColorShare(int _nColor) {
    int nRed = (int) _nColor/65536;
    int nRedModulo = _nColor % 65536;
    int nGreen = (int) (nRedModulo / 256);
    int nGreenModulo = (nRedModulo % 256);
    int nBlue = nGreenModulo;
    return nRed;
}

public static int getGreenColorShare(int _nColor) {
    int nRed = (int) _nColor/65536;
    int nRedModulo = _nColor % 65536;
    int nGreen = (int) (nRedModulo / 256);
    return nGreen;
}

public static int getBlueColorShare(int _nColor) {
    int nRed = (int) _nColor/65536;
    int nRedModulo = _nColor % 65536;
    int nGreen = (int) (nRedModulo / 256);
    int nGreenModulo = (nRedModulo % 256);
    int nBlue = nGreenModulo;
    return nBlue;
}

The method isHighContrastModeActivated expects a <idl>com.sun.star.awt.XVclWindowPeer</idl> reference from any existing dialog control or of the dialog itself.

Issue https://www.openoffice.org/issues/show_bug.cgi?id=74568 addresses this problem and will certainly lead to a more elegant solution.

Rendering

The module <idlmodule>com.sun.star.awt</idlmodule> offers a set of interfaces to render graphics. These interfaces are not deprecated as they are used internally. Developers are advised not to use these interfaces because the future belongs to a new API called the SimpleCanvas API ( https://www.openoffice.org/gsl/canvas/api/rendering/XSimpleCanvas.html ). For this reason these interfaces shall only be briefly explained.

<idl>com.sun.star.awt.XDevice</idl> The pixel model is extremely device dependent because it is applicable to printers as well as to screens with all kind of resolutions. This interface provides information about a graphical output device. For example the method getFont() returns an object implementing <idl>com.sun.star.awt.XFont</idl> that describes a font on the respective device. The methods createBitmap() and createDisplayBitmap() create bitmap objects with the device depth (these objects are primarily used for internal use of graphic operations). The method createGraphics() returns an object providing a set of output operations by implementing the interface <idl>com.sun.star.awt.XGraphics</idl>. It offers methods to draw geometric figures like drawLine(), drawRect(), etc. and permits the assignment of clip regions that implement <idl>com.sun.star.awt.XRegion</idl>. By defining a clipping region the output is reduced to a certain area of a window in order to prevent other parts like the border or the menubar from being overdrawn by output operations. <idl>com.sun.star.awt.XRegion</idl> manages multiple rectangles which make up a region. Its main task is to perform adding, excluding, intersecting and moving operations on regions. A raster graphics image is defined by grid of pixels, that individually define a color. They are distinguished from vector graphics in that vector graphics represent an image through the use of geometric objects such as curves and polygons. The method setRasterOp() of <idl>com.sun.star.awt.XGraphics</idl> applies values specified in the enumeration <idl>com.sun.star.awt.RasterOperation</idl> on the pixels of a graphic.

Summarizing Example to Create a UNO Dialog

Last but not least, a final example shall give an overall demonstration about how a dialog is created. The aim of the dialog is to inspect an arbitrary UNO-object and display its supported services, exported interfaces, methods and properties. It uses the code fragments that were introduced in the previous chapters. These code fragments are encapsulated in the class UnoDialogSample, that is not listed here. The creation of the dialog is implemented within the main method. Before this takes place an UNO object – an empty writer document - is created. This code piece can of course be exchanged and only serves as an example UNO object. The class UnoDialogSample2 is a deduction of UnoDialogSample and incorporates all the functionality used to create and display this specific dialog. Keep in mind that all variables prefixed with “m_” are member variables defined in the constructor.

import com.sun.star.awt.PushButtonType;
import com.sun.star.awt.XControl;
import com.sun.star.awt.XDialog;
import com.sun.star.awt.XFixedText;
import com.sun.star.awt.XListBox;
import com.sun.star.awt.XWindow;
import com.sun.star.beans.MethodConcept;
import com.sun.star.beans.Property;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XIntrospection;
import com.sun.star.beans.XIntrospectionAccess;
import com.sun.star.beans.XMultiPropertySet;
import com.sun.star.beans.XPropertySet;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XServiceInfo;
import com.sun.star.lang.XTypeProvider;
import com.sun.star.reflection.XIdlMethod;
import com.sun.star.uno.Type;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;

public class UnoDialogSample2 extends UnoDialogSample {
    XIntrospectionAccess m_xIntrospectionAccess = null;
    Object m_oUnoObject = null;
    // define some constants used to set positions and sizes
    // of controls. For further information see
    // http://ui.openoffice.org/knowledge/DialogSpecificationandGuidelines.odt
    final static int nFixedTextHeight = 8;
    final static int nControlMargin = 6;
    final static int nDialogWidth = 250;
    final static int nDialogHeight = 140;
    // the default roadmap width == 80 MAPs
    final static int nRoadmapWidth = 80;
    final static int nButtonHeight = 14;
    final static int nButtonWidth = 50;

    /**
    * Creates a new instance of UnoDialogSample2
    */
    public UnoDialogSample2(XComponentContext _xContext, XMultiComponentFactory _xMCF, Object _oUnoObject) {
        super(_xContext, _xMCF);
        try {
            m_oUnoObject = _oUnoObject;
            Object o = m_xMCF.createInstanceWithContext("com.sun.star.beans.Introspection", m_xContext);
            XIntrospection m_xIntrospection = ( XIntrospection ) UnoRuntime.queryInterface(XIntrospection.class, o );
            // the variable m_xIntrospectionAccess offers functionality to access all methods and properties
            // of a variable
            m_xIntrospectionAccess = m_xIntrospection.inspect(_oUnoObject);
        } catch (com.sun.star.uno.Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String args[]) {
        UnoDialogSample2 oUnoDialogSample2 = null;
        try {
            XComponentContext xContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
            if(xContext != null )
                System.out.println("Connected to a running office ...");
            XMultiComponentFactory xMCF = xContext.getServiceManager();
            PropertyValue[] aPropertyValues = new PropertyValue[]{};
            // create an arbitrary Uno-Object - in this case an empty writer document..
            Object oDesktop =xMCF.createInstanceWithContext("com.sun.star.frame.Desktop", xContext);
            XComponentLoader xComponentLoader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class, oDesktop);
            Object oUnoObject = xComponentLoader.loadComponentFromURL("private:factory/swriter", "_default", 0, aPropertyValues);

            // define some coordinates where to position the controls
            final int nButtonPosX = (int)((nDialogWidth/2) - (nButtonWidth/2));
            final int nButtonPosY = nDialogHeight - nButtonHeight - nControlMargin;
            final int nControlPosX = nRoadmapWidth + 2*nControlMargin;
            final int nControlWidth = nDialogWidth - 3*nControlMargin - nRoadmapWidth;
            final int nListBoxHeight = nDialogHeight - 4*nControlMargin - nButtonHeight;
            oUnoDialogSample2 = new UnoDialogSample2(xContext, xMCF, oUnoObject);
            oUnoDialogSample2.initialize( new String[] {"Height", "Moveable", "Name","PositionX","PositionY", "Step", "TabIndex","Title","Width"},
            new Object[] { new Integer(nDialogHeight), Boolean.TRUE, "Dialog1", new Integer(102),new Integer(41), new Integer(1), new Short((short) 0), "Inspect a Uno-Object", new Integer(nDialogWidth)});
            String sIntroLabel = "This Dialog lists information about a given Uno-Object.\nIt offers a view to inspect all suppported servicenames, exported interfaces, methods and properties.";
            oUnoDialogSample2.insertMultiLineFixedText(nControlPosX, 27, nControlWidth, 4, 1, sIntroLabel);
            // get the data from the UNO object...
            String[] sSupportedServiceNames = oUnoDialogSample2.getSupportedServiceNames();
            String[] sInterfaceNames = oUnoDialogSample2.getExportedInterfaceNames();
            String[] sMethodNames = oUnoDialogSample2.getMethodNames();
            String[] sPropertyNames = oUnoDialogSample2.getPropertyNames();
            // add controls to the dialog...
            oUnoDialogSample2.insertListBox(nControlPosX, nControlMargin, nListBoxHeight, nControlWidth, 2, sSupportedServiceNames);
            oUnoDialogSample2.insertListBox(nControlPosX, nControlMargin, nListBoxHeight, nControlWidth, 3, sInterfaceNames);
            oUnoDialogSample2.insertListBox(nControlPosX, nControlMargin, nListBoxHeight, nControlWidth, 4, sMethodNames);
            oUnoDialogSample2.insertListBox(nControlPosX, nControlMargin, nListBoxHeight, nControlWidth, 5, sPropertyNames);
            oUnoDialogSample2.insertButton(oUnoDialogSample2, nButtonPosX, nButtonPosY, nButtonWidth, "~Close", (short) PushButtonType.OK_value);
            oUnoDialogSample2.insertHorizontalFixedLine(0, nButtonPosY - nControlMargin, nDialogWidth, "");
            // create the windowpeer;
            // it must be kept in mind that it must be created after the insertion of the controls
            // (see http://qa.openoffice.org/issues/show_bug.cgi?id=75129)
            oUnoDialogSample2.createWindowPeer();
            // add the roadmap control. Note that the roadmap may not be created before the windowpeer of the dialog exists
            // (see http://qa.openoffice.org/issues/show_bug.cgi?id=67369)
            oUnoDialogSample2.addRoadmap(oUnoDialogSample2.getRoadmapItemStateChangeListener());
            oUnoDialogSample2.insertRoadmapItem(0, true, "Introduction", 1);
            oUnoDialogSample2.insertRoadmapItem(1, true, "Supported Services", 2);
            oUnoDialogSample2.insertRoadmapItem(2, true, "Interfaces", 3);
            oUnoDialogSample2.insertRoadmapItem(3, true, "Methods", 4);
            oUnoDialogSample2.insertRoadmapItem(4, true, "Properties", 5);
            oUnoDialogSample2.m_xRMPSet.setPropertyValue("CurrentItemID", new Short((short) 1));
            oUnoDialogSample2.m_xRMPSet.setPropertyValue("Complete", Boolean.TRUE);
            oUnoDialogSample2.xDialog = (XDialog) UnoRuntime.queryInterface(XDialog.class, UnoDialogSample2.m_xDialogControl);
            oUnoDialogSample2.xDialog.execute();
            } catch( Exception ex ) {
                ex.printStackTrace(System.out);
            }
            finally {
            //make sure always to dispose the component and free the memory!
            if (oUnoDialogSample2 != null) {
                if (oUnoDialogSample2.m_xComponent != null) {
                    oUnoDialogSample2.m_xComponent.dispose();
                }
            }
        }
    }

    public String[] getMethodNames() {
        String[] sMethodNames = new String[]{};
        try {
            XIdlMethod[] xIdlMethods = m_xIntrospectionAccess.getMethods(MethodConcept.ALL);
            sMethodNames = new String[xIdlMethods.length];
            for (int i = 0; i < xIdlMethods.length; i++) {
                sMethodNames[i] = xIdlMethods[i].getName();
            }
        }
        catch( Exception e ) {
            System.err.println( e );
        }
        return sMethodNames;
    }

    // returns the names of all supported servicenames of a UNO object
    public String[] getSupportedServiceNames() {
        String[] sSupportedServiceNames = new String[]{};
        // If the Uno-Object supports "com.sun.star.lang.XServiceInfo"
        // this will give access to all supported servicenames
        XServiceInfo xServiceInfo = ( XServiceInfo ) UnoRuntime.queryInterface( XServiceInfo.class, m_oUnoObject);
        if ( xServiceInfo != null ) {
            sSupportedServiceNames = xServiceInfo.getSupportedServiceNames();
        }
        return sSupportedServiceNames;
    }

    // returns the names of all properties of a UNO object
    protected String[] getPropertyNames() {
        String[] sPropertyNames = new String[]{};
        try {
            Property[] aProperties = m_xIntrospectionAccess.getProperties(com.sun.star.beans.PropertyConcept.ATTRIBUTES + com.sun.star.beans.PropertyConcept.PROPERTYSET);
            sPropertyNames = new String[aProperties.length];
            for (int i = 0; i < aProperties.length; i++) {
                sPropertyNames[i] = aProperties[i].Name;
            }
        }
        catch( Exception e ) {
            System.err.println( e );
        }
        return sPropertyNames;
    }

    // returns the names of all exported interfaces of a UNO object
    protected String[] getExportedInterfaceNames() {
        Type[] aTypes = new Type[]{};
        String[] sTypeNames = new String[]{};
        // The XTypeProvider interfaces offers access to all exported interfaces
        XTypeProvider xTypeProvider = ( XTypeProvider ) UnoRuntime.queryInterface( XTypeProvider.class, m_oUnoObject);
        if ( xTypeProvider != null ) {
            aTypes = xTypeProvider.getTypes();
            sTypeNames = new String[aTypes.length];
            for (int i = 0; i < aTypes.length - 1; i++) {
                sTypeNames[i] = aTypes[i].getTypeName();
            }
        }
        return sTypeNames;
    }

    public XListBox insertListBox(int _nPosX, int _nPosY, int _nHeight, int _nWidth, int _nStep, String[] _sStringItemList) {
        XListBox xListBox = null;
        try {
            // create a unique name by means of an own implementation...
            String sName = createUniqueName(m_xDlgModelNameContainer, "ListBox");
            // create a controlmodel at the multiservicefactory of the dialog model...
            Object oListBoxModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlListBoxModel");
            XMultiPropertySet xLBModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oListBoxModel);
            // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
            xLBModelMPSet.setPropertyValues(
            new String[] {"Dropdown", "Height", "Name", "PositionX", "PositionY", "ReadOnly", "Step", "StringItemList", "Width" } ,
            new Object[] {Boolean.FALSE, new Integer(_nHeight), sName, new Integer(_nPosX), new Integer(_nPosY), Boolean.TRUE, new Integer(_nStep), _sStringItemList, new Integer(_nWidth)});
            m_xDlgModelNameContainer.insertByName(sName, xLBModelMPSet);
        } catch (com.sun.star.uno.Exception ex) {
            throw new java.lang.RuntimeException("cannot happen...");
        }
        return xListBox;
    }

    public void insertMultiLineFixedText(int _nPosX, int _nPosY, int _nWidth, int _nLineCount, int _nStep, String _sLabel) {
        try {
            // create a unique name by means of an own implementation...
            String sName = createUniqueName(m_xDlgModelNameContainer, "Label");
            int nHeight = _nLineCount * nFixedTextHeight;
            // create a controlmodel at the multiservicefactory of the dialog model...
            Object oFTModel = m_xMSFDialogModel.createInstance("com.sun.star.awt.UnoControlFixedTextModel");
            XMultiPropertySet xFTModelMPSet = (XMultiPropertySet) UnoRuntime.queryInterface(XMultiPropertySet.class, oFTModel);
            // Set the properties at the model - keep in mind to pass the property names in alphabetical order!
            xFTModelMPSet.setPropertyValues(
            new String[] {"Height", "Label", "MultiLine", "Name", "PositionX", "PositionY", "Step", "Width"},
            new Object[] { new Integer(nHeight), _sLabel, Boolean.TRUE, sName, new Integer(_nPosX), new Integer(_nPosY), new Integer(_nStep), new Integer(_nWidth)});
            // add the model to the NameContainer of the dialog model
            m_xDlgModelNameContainer.insertByName(sName, oFTModel);
        } catch (com.sun.star.uno.Exception ex) {
            /* perform individual exception handling here.
            * Possible exception types are:
            * com.sun.star.lang.IllegalArgumentException,
            * com.sun.star.lang.WrappedTargetException,
            * com.sun.star.container.ElementExistException,
            * com.sun.star.beans.PropertyVetoException,
            * com.sun.star.beans.UnknownPropertyException,
            * com.sun.star.uno.Exception
            */
            ex.printStackTrace(System.out);
        }
    }
// end of class
}

Heckert GNU white.svg

Content on this page is licensed under the Public Documentation License (PDL).