5
votes

I'd like to develop a network graph application for Flex - imagine placing nodes on a Canvas and connecting them with links. The nodes should have editable text and other UI components.

I'm trying to find examples of creating an entirely new UI component from scratch, but all I've been able to find are trivial examples that extend existing components: a RedButton that extends Button, for example, or a ComboBox that has states to choose from.

My main question is, what ActionScript method defines the drawing of a component? What is the ActionScript equivalent of Java's paint() method?

5

5 Answers

5
votes

You want to create a component that overrides the updateDisplayList method, and do your drawing in there:

override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
{
  super.updateDisplayList( unscaledWidth, unscaledHeight );

  // The drawing API is found on the components "graphics" property
  graphics.clear();
  graphics.lineTo( 0, unscaledWidth );
  // etc
}

More information can be found here: http://livedocs.adobe.com/flex/3/html/help.html?content=ascomponents_advanced_3.html

4
votes

I would suggest looking at the flexlib project if you need examples of custom components.

There's good general info in the livedocs here

Although you can create custom components in MXML and in ActionScript, I would recommend implementing them in ActionScript.

In short this is what you need to do:

When you create a custom component in ActionScript, you have to override the methods of the UIComponent class. You implement the basic component structure, the constructor, and the createChildren(), commitProperties(), measure(), layoutChrome(), and updateDisplayList() methods.

3
votes

I recommend reading the 5-part tutorial series by Peter Ent on creating custom components. Here is the link to Part 1.

Also recommended, tutorial series on ItemRenderers and ItemEditors.

1
votes

Chapter 19 of Programming Flex 2 by Kazoun and Lott show the construction event model as well as the refresh event model.

In short, the Flex component structure assumes that you have properties of the object that affect its appearance. Instead of applying changes immediately, it allows property mutators to invalidate the component's "content" (e.g. text) via the inherited invalidateProperties() method. One also calls invalidateSize() when a property change will, ummm, change the size of the component, and invalidateDisplayList() when things need to be re-drawn (as opposed to just having different text).

This invalidation model optimizes the work of the component. It does not measure itself unless it knows it changed size; it does not place and draw itself unless something called invalidateDisplayList() since the last time it updated its layout; and it does not move its properties' values into its subcomponents unless it knows those values have changed.

Cheers

1
votes

The typical behavior is to subclass an existing component, mainly because so much of the work of implementing the functionality of so many of the most typical kinds of components is already done for you -- you just have to know which component most resembles the one you want to create. (A challenge in its own right, given how many there are.)

If you like, though, you can create a pretty bare-bones UIComponent "from scratch" simply by extending UIComponent (which'll give you all the baseline stuff), or I suppose, if you're really going for minimalism, and you're up for a challenge, you can just implement IUIComponent, and define each interface method manually. If you do choose to go that second route, do yourself a favor and listen to this talk first -- it's an in-depth discussion of the Flex component architecture, given by one of the engineers on the Flex team. I recommend it often, and highly; it's excellent, and it clarifies a number of component-development details that still aren't all that well documented. Extremely valuable stuff if you're going to be building non-trivial custom components of the kind you're describing.

Hope it helps. Good luck!