|
Simple
visual components are subclasses of existing Flex components that modify
the appearance of the component by using skins or styles, or add
new functionality to the component. For example, you add a new event
type to a Button control,
or modify the default styles or skins of a DataGrid control.
For more information, see Create simple visual components in ActionScript.
In advanced components, you typically perform the following actions:
Modify the basic functionality or logic of an existing
component.
Create a composite component that encapsulates two or more
components within it.
Create a skinnable component by creating a subclass of the SkinnableComponent class.
A
skinnable component uses two files: one for the component definition
and one for the skin definition. Create a Spark skinnable component
as a subclass of the SkinnableComponent class.
Create a nonskinnable component by creating a subclass of
the UIComponent or
other nonskinnable Spark class.
A nonskinnable component
is defined by a single file. Create a nonskinnable component as
a subclass of the UIComponent class. You can also create one from
a Spark class that does not have the SkinnableComponent class in
its class hierarchy, such a Group or DataGroup.
This topic contains several examples of Spark ActionScript components.
For more examples, examine the source code for the Spark components
in your Flex installation directory. The spark.components and spark.components.supportClasses
packages contain many of the Spark components mentioned in this topic.
Spark skinnable components and skin classesWhen creating an skinnable Spark component in ActionScript,
you create two classes: the component class and the skin class.
The component class defines the core behavior of the component.
This behavior includes defining the events dispatched by the component,
the data that the component represents, the skin parts implemented
by the skin class, and the view states that the skin class supports.
The skin class manages the visual appearance of the component
and creates visual subcomponents. The skin class defines the default
layout of the component, its default size, the supported view states,
graphics, and data representation.
About overriding protected UIComponent methods for Spark componentsAll Flex visual components are subclasses of the UIComponent class.
Therefore, visual components inherit the methods, properties, events,
styles, and effects defined by the UIComponent class.
To create an advanced visual component, you must implement a
class constructor. Also, you optionally override one or more of
the following protected methods of the UIComponent class:
UIComponent method
|
Description
|
|
|
Commits any changes to component properties,
either to make the changes occur at the same time or to ensure that
properties are set in a specific order.
For more information,
see Implementing the commitProperties() method for Spark components.
|
|
|
Creates any child components of the component.
For example, the Halo ComboBox control contains a Halo TextInput
control and a Halo Button control as child components.
Typically,
you do not implement this method in a Spark component because any
child components are defined in the skin class.
This topic
does not describe how to implement the createChildren() method.
For more information, see the example for creating a Halo component
in Implementing the createChildren() method for MX components.
|
|
|
Sets the default size and default minimum
size of the component.
You typically do not have to implement
this method for Spark components. The default size of a Spark component
is defined by the skin class, and by the children of the skin class.
You also set the minimum and maximum sizes of the component in the
root tag of the skin class.
This topic does not describe how
to implement the measure() method. For more information,
see the example for creating a MX components in Implementing the measure() method for MX components.
|
|
|
Sizes and positions the children of the
component on the screen based on all previous property and style settings,
and draws any skins or graphic elements used by the component. The
parent container for the component determines the size of the component
itself.
Typically, you do not have to implement this method
for Spark components. A few Spark components, such as spark.components.supportClasses.SkinnableComponent,
do implement it. The SkinnableComponent class implements it to pass
sizing information to the component's skin class.
This topic
does not describe how to implement the updateDisplayList() method.
For more information, see the example for creating a Halo component
in Implementing the updateDisplayList() method for MX components.
|
Component users do not call these methods directly; Flex calls
them as part of the initialization process of creating a component,
or when other method calls occur. For more information, see About the component instantiation life cycle for MX components.
About overriding SkinnableComponent methods for Spark componentsAll Spark skinnable components are subclasses of the SkinnableComponent class.
Therefore, skinnable components inherit the methods, properties,
events, styles, and effects defined by the SkinnableComponent class.
To create an skinnable Spark component, you optionally override
one or more of the following methods of the SkinnableComponent class:
SkinnableComponent method
|
Description
|
attachSkin()
detachSkin()
|
Called automatically by the commitProperties() method
when a skin is added, attachSkin(), or a skin is
removed, detachSkin(). You can optionally implement
these methods to add a specific behavior to a skin.
Typically
you do not implement these methods.
|
partAdded()
partRemoved()
|
Called automatically when a skin part is
added or removed. You typically override partAdded() to attach
event handlers to the skin part, configure the skin part, or perform
other actions when a skin part is added. Implement the partRemoved() method
to remove the even handlers added in partAdded().
For
more information, see Implementing the partAdded() and partRemoved() methods for skinnable components for Spark components.
|
getCurrentSkinState()
|
Called automatically by the commitProperties() method
to set the view state of the skin class.
For more information,
see Implementing the getCurrentSkinState() method for skinnable components for Spark components.
|
Component users do not call these methods directly; Flex calls
them as part of the initialization process of creating a component,
or when other method calls occur. For more information, see About the component instantiation life cycle for MX components.
About the invalidation methods for Spark componentsDuring the lifetime of a component, your application might
modify the component by changing its size or position, modifying
a property that controls its display, or modifying a style or skin
property of the component. For example, you might change the font
size of the text displayed in a component. As part of changing the
font size, the component’s size might also change, which requires Flex
to update the layout of the application. The layout operation might
require Flex to invoke the commitProperties(), measure(), getCurrentSkinState(),
and the updateDisplayList() methods of your component.
Your application can programmatically change the font size of
a component much faster than Flex can update the layout of an application.
Therefore, you only want to update the layout after you are sure
that you’ve determined the final value of the font size.
In another scenario, when you set multiple properties of a component,
such as the label and icon properties
of a Button control, you want the commitProperties(), measure(), getCurrentSkinState(),
and updateDisplayList() methods to execute only
once, after all properties are set. You do not want these methods
to execute when you set the label property, and
then execute again when you set the icon property.
Also, several components might change their font size at the
same time. Rather than updating the application layout after each
component changes its font size, you want Flex to coordinate the
layout operation to eliminate any redundant processing.
Flex uses an invalidation mechanism to synchronize modifications
to components. Flex implements the invalidation mechanism as a set
of methods that you call to signal that something about the component
has changed and requires Flex to call the component’s commitProperties(), measure(), getCurrentSkinState(),
or updateDisplayList() methods.
The following table describes the invalidation methods:
Invalidation method
|
Description
|
|
|
Marks a component so that its updateDisplayList() method
gets called during the next screen update.
|
|
|
Marks a component so that its commitProperties() method
gets called during the next screen update.
|
|
|
Marks a component so that its measure() method
gets called during the next screen update.
|
invalidateSkinState()
|
Marks a component so that its commitProperties() method
gets called on the next screen update to change the view state of
the skin class. The commitProperties() method calls
the getCurrentSkinState() method.
|
When a component calls an invalidation method, it signals to
Flex that the component must be updated. When multiple components
call invalidation methods, Flex coordinates updates so that they
all occur together during the next screen update.
Typically, component users do not call the invalidation methods
directly. Instead, they are called by the component’s setter methods,
or by any other methods of a component class as necessary. For more
information and examples, see Implementing the commitProperties() method for MX components.
About the Spark component instantiation life cycleThe component instantiation
life cycle describes the sequence of steps that occur when you create
a component object from a component class. As part of that life
cycle, Flex automatically calls component methods, dispatches events, and
makes the component visible.
The following example creates a Button control
in ActionScript and adds it to a Group container:
// Create a Group container.
var groupContainer:Group = new Group();
// Configure the Group container.
groupContainer.x = 10;
groupContainer.y = 10;
// Create a Button control.
var b:Button = new Button()
// Configure the button control.
b.label = "Submit";
...
// Add the Button control to the Box container.
groupContainer.addElement(b);
The following steps show what occurs when you execute the code
to create the Button control, and add the control to the container:
You call the component’s constructor, as the following
code shows:
// Create a Button control.
var b:Button = new Button()
You configure the component by setting its properties, as
the following code shows:
// Configure the button control.
b.label = "Submit";
Component setter methods might
call the invalidateProperties(), invalidateSize(), invalidateSkinState(),
or invalidateDisplayList() methods.
You call the addElement() method to add
the component to its parent, as the following code shows:
// Add the Button control to the Box container.
gropContainer.addElement(b);
Flex then performs the
following actions:
Sets the parent property for the component
to reference its parent container.
Computes the style settings for the component.
Dispatches the preinitialize event on the
component.
Calls the component’s createChildren() method.
For skinnable components, this causes a call to attachSkin(),
which calls partAdded(), for all static parts defined
in the skin file.
Calls the invalidateProperties(), invalidateSize(), invalidateSkinSate(),
and invalidateDisplayList() methods to trigger
calls to the commitProperties(), measure(), getCurrentSkinState(),
or updateDisplayList() methods during the next render event.
The
only exception to this rule is that Flex does not call the measure() method
when the user sets the height and width of the component.
Dispatches the initialize event on the component.
At this time, all of the component’s children are initialized, but
the component has not been sized or processed for layout. You can
use this event to perform additional processing of the component
before it is laid out.
Because the initialize event
is dispatched early in the component's startup sequence, make sure
that none of your processing causes the component to invalidate
itself. You typically perform any final processing during the creationComplete event.
Dispatches the elementAdd event on the parent
container.
Dispatches the initialize event on the parent
container.
During the next render event, Flex performs
the following actions:
Calls the component’s commitProperties() method.
For skinnable components, the commitProperties() method
calls the getCurrentSkinState() methods.
Calls the component’s measure() method.
Calls the component’s updateDisplayList() method.
Flex dispatches additional render events
if the commitProperties(), measure(),
or updateDisplayList() methods call the invalidateProperties(), invalidateSize(), invalidateSkinSate(),
or invalidateDisplayList() methods.
After the last render event occurs, Flex
performs the following actions:
Makes the component
visible by setting the visible property to true.
Dispatches the creationComplete event on
the component. The component is sized and processed for layout.
This event is only dispatched once when the component is created.
Dispatches the updateComplete event on the
component. Flex dispatches additional updateComplete events
whenever the layout, position, size, or other visual characteristic
of the component changes and the component is updated for display.
Most of the work for configuring a component occurs when you
add the component to a container by using the addElement() method.
That is because until you add the component to a container, Flex
cannot determine its size, set inheriting style properties, or draw
it on the screen.
You can also define your application in MXML, as the following
example shows:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark">
<s:Group>
<s:Button label="Submit"/>
</s:Group>
</s:Application>
The sequence of steps that Flex executes when creating a component
in MXML are equivalent to the steps described for ActionScript.
You can remove a component from a container by using the removeElement() method.
If there are no references to the component, it is eventually deleted
from memory by the garbage collection mechanism of Adobe® Flash® Player
or Adobe® AIR™.
About the steps for creating a Spark componentWhen you implement a component, you override component
methods, define new properties, dispatch new events, or perform
any other customizations required by your application.
To implement your component, follow these general steps:
Create the skin class for the component. You typically
create the skin class in MXML. For more information on skins, see Spark Skinning.
Create the component’s ActionScript class file.
For a skinnable component, extend one of the base classes,
such as SkinnableComponent, or a subclass of class SkinnableComponent.
For a nonskinnable component, extend UIComponent or a Spark class
that does not have SkinnableComponent in it class hierarchy.
Implement the constructor.
Implement the UIComponent.createChildren() method.
You rarely have to implement this method for Spark components.
Implement the UIComponent.commitProperties() method.
Implement the UIComponent.measure() method.
You rarely have to implement this method for Spark components.
Implement the UIComponent.updateDisplayList() method.
You rarely have to implement this method for Spark components.
For a skinnable component, implement the SkinnableComponent.partAdded() and SkinnableComponent.partRemoved() methods.
For a skinnable component, implement the SkinnableComponent.getCurrentSkinState() method.
Add properties, methods, styles, events, and metadata.
Deploy the component as an ActionScript file or as a SWC
file.
For more information about MXML tag properties and embedding
graphic and skin files, see Create simple visual components in ActionScript.
You do not have to override all component methods to define a
new component. You only override the methods required to implement
the functionality of your component. If you create a subclass of
an existing component, such as Button, you implement only the methods
necessary for you to add any new functionality to the component.
About interfacesFlex uses
interfaces to divide the basic functionality of components into
discrete elements so that they can be implemented piece by piece.
For example, to make your component focusable, it must implement
the IFocusManagerComponent interface; to let it participate in the
layout process, it must implement ILayoutClient interface.
To simplify the use of interfaces, the UIComponent class implements
all of the interfaces defined in the following table, except for
the IFocusManagerComponent interface. However, many subclasses of
UIComponent implement the IFocusManagerComponent interface.
Therefore, if you create a subclass of the UIComponent class
or subclass of UIComponent, such as SkinnableComponent, you do not
have to implement these interfaces. But, if you create a component
that is not a subclass of UIComponent, and you want to use that
component in Flex, you might have to implement one or more of these
interfaces.
The following table lists the main interfaces implemented by
Flex components:
Interface
|
Use
|
IAdvancedStyleClient
|
Indicates that the component supports the
advanced style subsystem.
|
IAutomationObject
|
Indicates that a component is an object
within the automation object hierarchy.
|
IChildList
|
Indicates the number of children in a container.
|
IConstraintClient
|
Indicates that the component support layout
constraints.
|
IDeferredInstantiationUIComponent
|
Indicates that a component or object can
effect deferred instantiation.
|
IFlexDisplayObject
|
Specifies the interface for skin elements.
|
IFlexModule
|
indicates that the component can be used
with module factories
|
IFocusManagerComponent
|
Indicates that a component or object is
focusable, which means that the components can receive focus from
the FocusManager. The UIComponent class does not implement IFocusable
because some components are not intended to receive focus.
|
IInvalidating
|
Indicates that a component or object can
use the invalidation mechanism to perform delayed, rather than immediate,
property commitment, measurement, and drawing or layout.
|
ILayoutManagerClient
|
Indicates that a component or object can
participate in the LayoutManager's commit, measure, and update sequence.
|
IPropertyChangeNotifier
|
Indicates that a component supports a specialized
form of event propagation.
|
IStateClient
|
Indicates that the component supports view
states.
|
IToolTipManagerClient
|
Indicates that a component has a toolTip property,
and therefore is monitored by the ToolTipManager.
|
IUIComponent
|
Defines the basic set of APIs that you must
implement in order to be a child of layout containers and lists.
|
IValidatorListener
|
Indicates that a component can listen for
validation events, and therefore show a validation state, such as
a red border and error tooltips.
|
IVisualElement
|
Indicates that the component can be laid
out and displayed in a Spark application.
|
|
|
|