Created

23 August 2011

This article aims to provide answers to some of the most frequently asked questions about Design View extensions.

Why do I need Design view extensions?
Who would find Design View extensions useful?
What are the extension features that I should expose to users?
How can I make a component visible under the correct group in the Components view?
How do I go about designing the design.xml file?
How do I associate an icon with the component?
How do I set the properties for a component using the Property Inspector?
What are the different property types that you can define?
What are the default property values?
How can I include or exclude components?
How can I exclude a SWC from the Design view?
Can you enable custom code generation for components?
How can you create a customized Design View?
How do you create an extension class?
How do you compile and package your extension class?

Why do I need Design view extensions?

When you develop applications in Flash Builder, you use the MXML editor to edit MXML files. The MXML editor has two modes: Source and Design. You use the Source mode for editing code and the Design mode for visually laying out and designing your applications. When you are in the Design mode, the available components are displayed in the Components view. You can drag-and-drop a component from the Components view to the Design view. While doing so, Flash Builder generates the code required to display the object in the Design view. The Design and Source modes are synchronized and changes in one mode are immediately reflected in the other.

Sometimes, there are components that have a customized look-and-feel in the Design view, but the corresponding code is not reflected in the Source view. To expose these functionalities to users of your custom library, you use Design view extensions.

Who would find Design View extensions useful?

Typically, a custom UI controls library developer would find Design View extensions useful.

What are the extension features that I should expose to users?

We will discuss various features of the Design view to help you decide the features that you would like to expose to users. When you open an MXML file from a project, you see the Source and Design tabs at the top of the editor area (see Figure 1), which lets you quickly switch between the Source and Design modes.

In Design mode, you see the Components view, Outline view, and Property Inspector.

The Components view displays controls that can be dragged and dropped to the Design view (see Figure 2). You can see that the components are grouped under Custom, Controls, Layouts, etc. You can make your component visible under an appropriate group, or you can also create your own group of components.

You can choose to show only recommended components (see Figure 3). For example, the Button component has both MX Button and Spark Button components. When you select "Only Show Recommended Component", only the Spark button appears in the Components view. When you deselect this option, you can see both Spark and MX controls.

How can I make a component visible under the correct group in the Components view?

To make a component visible under the correct group, do the following:

  1. Create a design.xml file and add it as an asset.
  2. Create an icon

How do I go about designing the design.xml file?

A sample design.xml file looks like this:

<?xml version="1.0"?> <design version="2"> <categories> <category id="myControls" label="MyCustomControls" defaultExpand="true"/> <category id="myControls_combined" filteredViewOnly="true" label="MyCustomControls_Filtered" defaultExpand="true"/> </categories> <components> <component name="MyComponent" displayName=" MySpecialComponent " category="myControls" filteredViewCategory="myControls_combined" > </component> </components> </design>

Tag

Attributes

Description

Design

Version

Specify the version as "2" to let Flash Builder recognize this tag.

If you do not specify the correct version number, the XML file is not recognized by the Design View, and you get an error message.

Categories

Id

Specifies the categories that must appear in the Categories view.

label

Category name

filteredViewOnly

Appears when you select the "show only recommended components" option.

Components

Name

Fully-qualified component class name

displayName

Component name displayed in the Components view

Category

Category ID

filteredViewCategory

Displays the categories that must appear when you specify the filteredViewOnly attribute.

For example, if you have both MX and Spark versions of the component, for the MX component, you can specify the filteredViewCategory="" and for the Spark component, you can specify the categories.

The MyCusotmControls group shows MySpecialComponent under it (see Figure 5). You can drag and drop the MySpecialComponent to create an instance in the Design view.

If your component is not associated with an icon, it displays the custom component icon as shown in figure 5.

How do I associate an icon with the component?

To associate an icon with the component, use the IconFile metadata tag, shown in the following code:

<s:Group xmlns:fx=http://ns.adobe.com/mxml/2009 xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" width="156" height="106" chromeColor="#6CE4C4" contentBackgroundColor="#EEAFAF"> <fx:Metadata> [IconFile("myIcon.png")] </fx:Metadata> <s:Button x="20" y="26" label="Button"/> <s:CheckBox x="20" y="64" label="CheckBox"/> </s:Group>

If the ActionScript file and IconFile metadata can be added above the class start

[IconFile("myIcon.png")] Public class MyClass extends….. { }
  • Place the icon file at the same location where the component file is also present.
  • In the library compilation, ensure to add the icon file also in the assets.

You should be able to see your component icon in the Components view, Outline view, and in the Property Inspector (see Figure 6).

How do I set the properties for a component using the Property Inspector?

The Property Inspector appears on the right-hand side of the Design view and displays the components properties.

The common properties that a user would normally edit for a component should be made available in the Common section. For example, ID, label of a button, and onClick event hander for a button.

The properties in the Common section can be added by specifying details in the desing.xml file as follows:

For example, you can have a customLogin component that has a component title and a support button label. Users can specify these values while creating a new component:

<?xml version="1.0"?> <design version="2"> <categories> <category id="myControls" label="MyCustomControls" defaultExpand="true"/> <category id="myControls_combined" filteredViewOnly="true" label="MyCustomControls_Filtered" defaultExpand="true"/> </categories> <components> <component name="CustomLogin" displayName=" MySpecialLogin " category="myControls" filteredViewCategory="myControls_combined" > <mxmlProperties> <textfield id="title" name="Panel Title"/> <textfield id="supportButtonLabel" name="Support Button Label"/> </mxmlProperties> </component> </components> </design>

When you define the MXML Properties tag as shown in the example, the component is displayed in the Design view, and the Property Inspector appears in Figure 7:

What are the different property types that you can define?

The following property types can be defined:

TEXTFIELD

As shown in the above example you can use textField to represent editable text data.

COMBO

MXML syntax of the combo property is as follows:

<combo id="supportButtonLabelVisible" name ="Support Button Visible" /> <combo id=" sampleMultipleValue " name ="Sample Multi Value" />

As the property name indicates, comboBox displays multiple values. For example, a Boolean variable, or a variable that has a known set of allowed values. The component should specify the enumeration using metadata as follows:

public var supportButtonLabelVisible:Boolean = true; [Inspectable(category="General", enumeration="30,50,100", defaultValue="20")] public var sampleMultipleValue:int = 0;

The Property Inspector displays the values as shown in Figure 8.

EVENTEXTFIELD

Use this property to expose the common events that a user can click on to generate the event handler. For example, a radio button click event in Figure 9.

<eventTextfield id="click" name="Click"/>

DATATEXTFIELD

The dataTextfield property has two usages:

  • showEvent – true

Here the property name is considered as the event name and a user can use this property to generate event handlers. You can also choose to generate a service call.

To do so, you can expose your favorite events and let the user generate the handlers for that event. For example, see the button click event in Figure 10.

<dataTextfield id="click" name="On click" showEvent="true"/>
  • showEvent – false

When you set showEvent to false, you can bind the service call result to a specific property. For example, see the List data provider in Figure 11.

<dataTextfield id="dataProider" name="Data Provider"

Other properties:

  • RendererTextField–use this property to create or edit an item renderer.
  • AssetFileChooser–use this property if your component needs  to select files for property values. You can either embed the file or specify it as a part of the project's assets.

There are other component-specific data types, which are not in the scope of this article.

What are the default property values?

You can set the default properties for your components as follows:

<defaultAttribute name="sampleMultipleValue" value="100"/> <defaultAttribute name="title" value="My Title"/>

The tag name is the defaultAttribute name and the property name is the value to be used while creating the object.

How can I include or exclude components?

You can include or exclude components based on project types. When you define your component, you can specify the types of projects that the component must be included in or excluded from.

Use the excludedFromProjectType property to exclude a component from a project type and the includeInProjectType property to include a component for a project type. You can specify this value at the component level or at the property level.

If you do not specify any value, the component will be applicable to all the project types, like, Flex, AIR, and mobile projects. You can currently specify a differentiation only between mobile and non-mobile projects.

How can I exclude a SWC from the Design view?

The Design view loads all the SWC files that are referenced from the project library path. At times, if your SWC has compatibility issues with the Design view, or if it contains AIR-specific features, the Design View reports problems while loading the SWC. An incompatible SWC is excluded from the Design View interpretation. However, if the SWC was meant only for non-UI classes, then you would not want the Design View to report problems. In such a scenario, you can exclude the SWC from the Design view interpretation.

To do so, create a design.xml file as follows:

<?xml version="1.0"?> <design version="2" excludeFromDesignView=”true”> </design>

Then, include the design.xml file in the SWC file.

Can you enable custom code generation for components?

If you have a complex component, you can to generate the sample code at runtime, such that it provides the same look-and-feel as in the Design view.

For example, consider the Chart component. When you drag-and-drop a Chart component, you see the chart in the design view. But when you launch the application, you do not see the chart in the running application.

Using custom code generation lets you understand the component usage and see a working sample.

Steps

  1. Create a custom LineChart

    Create a custom chart class, for example, MyLineChart , which is similar to LineChart . To do so, create a library project, and a MXML component that extends from the LineChart .

  2. Use the library in an application project

    When you include the library project in an application project, you will note that LineChart comes under the custom component section in the Design View. You can include the LineChart under a special category in the Design View. Note that this is however not needed to enable the custom code generation functionality.

  3. Drag-and-Drop the MyLineChart component

    When you drag-and-drop the MyLineChart component to the Design View, you see that the Design View renders the line chart with some data. When you try to launch the application with the MyLineChart in it, it shows an empty Line chart. That is, the data that is used to render that chart is only applicable in Design View. This data comes from the LineChart extension class.

    In this step, add an empty chart in the Design View and at run time. So, you need to nullify whatever data is added by the LineChart extension.

  4. Extend the extension class

    To extend the base extension class and remove the special data settings, create an ActionScript class MyLineChartExtension , and Override the create component as follows:

package { Import com.adobe.flexide.extensions.components.mx.charts.chartClasses.CartesianChartExtension; import flash.display.DisplayObject; public class MyLineChartExtension extends CartesianChartExtension { public override function createComponent(inItemType:String):DisplayObject{ // We ignore the actual data provider and always display sample data var item:DisplayObject = super.createComponent(inItemType); var chart:MyLineChart = MyLineChart(item); return chart; } }

Then, create the Chart component, and don't set the data.

Specify the extension in design.xml as follows:

<?xml version="1.0"?> <design version="2"> <categories> <category id="myControls" label="MyCustomControls" defaultExpand="true"/> <category id="myControls_combined" filteredViewOnly="true" label="MyCustomControls1" defaultExpand="true"/> </categories> <components> <component name="MyLineChart" excludeFromProjectType="mobile" displayName="MySpecialChart" category="myControls" filteredViewCategory="myControls_combined" > <designExtension class="MyLineChartExtension"/> </component> </components> </design>

When you include the library, and drag the chart to the Design View, you can see the empty chart in the Design View.

You can now generate the custom code so that the chart shows the data in the Design View and in the browser.

Inserter Java Extension class

To create a custom dialog or custom code generation, you need to create a Java extension for Flash Builder.

  1. In the plug-in, specify the extension details as follows:
<extension point="com.adobe.flexbuilder.mxmlmodel.componentInserters"> <componentInserter class="drophandlersample.MyLoginInserter"> </componentInserter> </extension>
  1. Implement com.adobe.flexbuilder.mxmlmodel.components.IComponentInserter from The MyLoginInserter class.
public class MyLineChartInserter extends AutoIDInserter implements IComponentInserter { public void insertComponent(IComponentInsertionManager componentInsertionManager, IComponentInsertParams params, boolean showDialog) { } }
  1. Specify the inserter class details in the design.xml for the applicable class, and specify the details of the code generation or custom dialog there.
<?xml version="1.0"?> <design version="2"> <categories> <category id="myControls" label="MyCustomControls" defaultExpand="true"/> <category id="myControls_combined" filteredViewOnly="true" label="MyCustomControls1" defaultExpand="true"/> </categories> <components> <component name="MyLineChart" excludeFromProjectType="mobile" displayName="MySpecialChart" inserterClass="drophandlersample.MyLineChartInserter" category="myControls" filteredViewCategory="myControls_combined"> <designExtension class="MyLineChartExtension" /> </component> </components> </design>

For this sample, assume we want to generate the data provider and the series details. So then the details are written in the instertComponent method of MyLineChartInserter .

See the sample code of MyLineChartInserter.

How can you create a customized Design View?

You can use extension classes to create a customized Design View. The following questions help you understand more about extension classes.

How do you create an extension class?

You create an extension class for your custom component. You extend from the extension that corresponds to your base class.

For example, if your class is extending from Group, your extension class must extend from GroupExtension class.

It is recommended to specify all the levels of the extension class. For example, if your class is MyLogin thatis extending from MyGroup . And MyGroup extends from the Spark Group. Then, it is recommended to create MyLoginExtension that extends from MyGroupExtension . Where, MyGroupExtension extends from GroupExtension .

How do you compile and package your extension class?

To compile the MyGroupExtension class, you need to provide the definition of the GroupExtension class and the MyGroupExtension class to the application that uses the MyGroup class. To do so, read this document.

A few methods of IComponentExtension are as follows:

createComponent

  • Creates a DisplayObject managed by the extension.
  • Override this function to create components in a different way. Or change the behavior of the object creation from the base class.

setProperty

  • Sets a property on the specified component.

* Returns a Boolean value to indicate if the extension set the property. If the value is false, the default handler sets the property. You can overwrite this value if the property needs special handling. For example, you can override this method to not allow animation for the in-progress indicator component.

setStyle

  • Sets a style on the specified component.

* Returns a Boolean value to indicate if the extension set the property. You can overwrite this value if the style needs special handling.

canShowBorder

  • Returns a value that indicates if the Design View should draw a border around the item. In the Design view, you have an option to draw a border around items. When you enable this option, the Design View draws a border around all the items. A border around items makes it easier to see the size and location of the items on the design surface. The default value of this function is false.

usesAbsolutePositioning

  • Returns a value that indicates if an item uses absolute positioning for laying out its children.
  • Override this function if you are creating a container that has its own layout rules and supports absolute positioning in some scenarios.

* Returns "" for absolute positioning, "vertical" for a vertical layout, and "horizontal" for a horizontal layout.

  • Returns a value that indicates if the item should is a container.
  • Extension classes that inherit from ContainerExtension return a value of true.
  • Override this function to return a value of false if you have a scenario where the component inherits from the Container but should not be treated as a container in the Design View.