Control Models and Shapes
There is more to know about form components in a document.
From Shapes, you already know about shapes. They are also part of a document model. The control shapes, com.sun.star.drawing.ControlShape are made to be tied to control models. They are specialized to fully integrate form control models into a document.
In theory, there can be a control shape without a model tied to it, or a control model which is part of the form component hierarchy, but not associated with any shape. In the first case, an empty shape is displayed in the document view. In the second case, you see nothing. It is possible to have a shape which is properly tied to a control model, but the control model is not part of the form component hierarchy. The model can not interact with the rest of the form layer. For example, it is unable to take advantage of its data awareness capabilities.
A complete object structure in a document model with respect to the components relevant for our form layer looks the following:
Programmatic Creation of Controls
As a consequence from the previous paragraph, we now know that to insert a form control, we need to insert a control shape and control model into the document's model.
The following code fragment accomplishes that:
/** creates a control in the document <nowiki><p>Note that <em>control<em> here is an incorrect terminology. What the method really does is it creates a control shape, together with a control model, and inserts them into the document model. This will result in every view to this document creating a control described by the model-shape pair.</p></nowiki> @param sFormComponentService the service name of the form component to create, e.g. "TextField" @param nXPos the abscissa of the position of the newly inserted shape @param nXPos the ordinate of the position of the newly inserted shape @param nWidth the width of the newly inserted shape @param nHeight the height of the newly inserted shape @return the property access to the control's model */ public static XPropertySet createControlAndShape(String sFormComponentService, int nXPos, int nYPos, int nWidth, int nHeight) throws java.lang.Exception { // let the document create a shape XMultiServiceFactory xDocAsFactory = (XMultiServiceFactory)UnoRuntime.queryInterface( XMultiServiceFactory.class, s_aDocument); XControlShape xShape = (XControlShape)UnoRuntime.queryInterface(XControlShape.class, xDocAsFactory.createInstance("com.sun.star.drawing.ControlShape")); // position and size of the shape xShape.setSize(new Size(nWidth * 100, nHeight * 100)); xShape.setPosition(new Point(nXPos * 100, nYPos * 100)); // and in a OOo Writer doc, the anchor can be adjusted XPropertySet xShapeProps = (XPropertySet)UnoRuntime.queryInterface(XPropertySet.class, xShape); TextContentAnchorType eAnchorType = TextContentAnchorType.AT_PAGE; if (classifyDocument(s_aDocument) == DocumentType.WRITER) { eAnchorType = TextContentAnchorType.AT_PARAGRAPH; } xShapeProps.setPropertyValue("AnchorType", eAnchorType); // create the form component (the model of a form control) String sQualifiedComponentName = "com.sun.star.form.component." + sFormComponentService; XControlModel xModel = (XControlModel)UnoRuntime.queryInterface(XControlModel.class, s_aMSF.createInstance(sQualifiedComponentName)); // knitt them xShape.setControl(xModel); // add the shape to the shapes collection of the document XShapes xDocShapes = (XShapes)UnoRuntime.queryInterface(XShapes.class, getDocumentDrawPage()); xDocShapes.add(xShape); // and outta here with the XPropertySet interface of the model XPropertySet xModelProps = (XpropertySet)UnoRuntime.queryInterface( XpropertySet.class, xModel); return xModelProps; }
Looking at the example above, the basic procedure is:
- create and initialize a shape
- create a control model
- announce the control model to the shape
- insert the shape into the shapes collection of a draw page
The above does not mention inserting the control model into the form component hierarchy, which is a contradiction of our previous discussion. We have previously said that every control model must be part of this hierarchy to prevent corrupted documents, but it is not harmful.
In every document, when a new control shape is inserted into the document, through the API or an interaction with a document's view, the control model is checked if it is a member of the model hierarchy. If it is not, it is automatically inserted. Moreover, if the hierarchy does not exist or is incomplete, for example, if the draw page does not have a forms collection, or this collection does not contain a form, this is also corrected automatically.
With the code fragment above applied to a new document, a logical form is created automatically, inserted into the forms hierarchy, and the control model is inserted into this form.
You may have noticed that there is nothing about the view. We only created a control model. As you can see in the complete example for this chapter, when you have an open document, and insert a model and a shape, a control (the visual representation) is also created or else you would not see anything that looks like a control.
The control and model have a model-view relationship. If the document window is open, this window is the document view. If the document or the model is modified by inserting a control model, the view for every open view for this document reacts appropriately and creates a control as described by the model. The DefaultControl property describes the service to be instantiated when automatically creating a control for a model.
Content on this page is licensed under the Public Documentation License (PDL). |