Can I have multiple classes in one file in MXML? - apache-flex

I have a classB that will only be used inside classA. However, classA is written as mxml, not actionscript code. Is it possible to nest classes in MXML or add another class after the root tag in the same .mxml file?
Clarification: I want both classes written in MXML within the same file, but I couldn't find anything in the Adobe documentation that specified how.

No, you can't define two classes in one MXML file, but you can have the same package (namespace) for both classes and make classB internal, so its only visible for classes within that package.

I believe you are looking for the fx:Component tag that allows you to define a new MXML document within an existing MXML document:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:local="*">
<fx:Declarations>
<fx:Component className="MyMXMLClass1">
<s:Group>
<s:Button label="MyMXMLClass1" />
</s:Group>
</fx:Component>
<fx:Component className="MyMXMLClass2">
<s:Group>
<s:Button label="MyMXMLClass2" />
</s:Group>
</fx:Component>
</fx:Declarations>
<s:VGroup>
<local:MyMXMLClass1 />
<local:MyMXMLClass2 />
</s:VGroup>
</s:Application>

If multiple levels of inheritance are required in the nested classes, and alternative to <fx:Component> (mentioned in a previous answer) is to use <fx:Library> for example:
<fx:Library>
<fx:Definition
name="MyClass"
>
<s:Group>
...
<s:/Group>
</fx:Definition>
</fx:Library>
...
<!-- Use MyClass later in the file. -->
<fx:MyClass ... />
The <fx:Library> must be at the top of the MXML file. This syntax allows for several nested class definitions in a row, and each can extend the previous via inheritance.

Related

Spark Custom Grid Header Renderer Style

I am trying to create a Header for DataGrid which will show the Label and TextInput. The code is:
<?xml version="1.0" encoding="utf-8"?>
<s:DefaultGridHeaderRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<mx:VBox paddingLeft="5" paddingTop="5" paddingRight="5" paddingBottom="5">
<s:Label text="{data.headerText}"/>
<s:TextInput width="100%" />
</mx:VBox>
</s:DefaultGridHeaderRenderer>
It somehow works but the problem is I am loosing the styles on the headers and the background is showing as white instead of the nice grey gradient.
I think I have to add the styling manually. Is there an easy way to do so?
Thanks
Styles are handled by ActionScript code in the item renderer. It's up to you to write that code in your own item renderer. For an example view the source code for the default header renderer. Or you can ignore styles, and just add a Rect behind the Vbox and set its fill properties to whatever you like.

What to use as base for a custom MXML component?

I'm using several custom MXML components in my Flex 4.5 application.
They all use absolute coordinates to place Image, Label, Line, etc. components and are currently based on a spark.components.BorderContainer:
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer
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="160" height="140" borderWeight="0"
creationComplete="init(event)">
<s:layout>
<s:BasicLayout />
</s:layout>
<s:Image id="_avatar" x="0" y="0" width="160" height="120" />
<s:Label id="_username" x="1" y="122" width="80" />
<s:Label id="_bid" x="80" y="122" width="40" textAlign="center" />
<s:Label id="_trix" x="120" y="122" width="36" textAlign="right" />
.... and so on: Images, Labels, Paths, Lines, Rects ....
</s:BorderContainer>
Then I've realized, that I probably don't have to use BorderContainer, because I don't draw/need any borders around my custom components.
But I don't know, what to take instead of it.
I've tried taking <mx:UIComponent> (and removing <s:Layout> tag above), but then I get the error:
'Image' declaration must be contained within the <Declarations> tag since it does not implement 'mx.core.IUIComponent'.
'Label' declaration must be contained within the <Declarations> tag since it does not implement 'mx.core.IUIComponent'.
Any suggestions please? Is there some simplest possible spark "container"? And do I need a "container" at all if I use (and want to use) absolute coordinates?
I recommend you to use s:Group. And you can omit layout declaration as far as BasicLayout is default layout.
UIComponent isn't container so it hasn't default placeholder for children to add them with MXML.

Extending MXML custom components via MXML

What I'd like to do: create an MXML component with some children, then extend it via MXML to create a new component with more children, without losing the original set.
In other words
create a component bc.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:BorderContainer 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="400" height="300">
<s:Button id="b1" label="button1"/>
</s:BorderContainer>
and then extend it to a separate component mc.mxml
<?xml version="1.0" encoding="utf-8"?>
<borderContainerX:bc xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:borderContainerX="borderContainerX.*">
<s:Button id="b2" y="100" label="button2"/>
</borderContainerX:bc>
and get a component with 2 buttons.
I've seen various threads on how this is either not possible (1) or on workarounds to accomplish this (2, 3) and have been wondering if something has changed with the advent of Flex 4 or if we're still stuck with these workarounds the last reply in thread 3 seems to hint at Flex 4 fixing it all?
In Flex 4, you will have to override your "mxmlContent" property setter in order to preserve your already defined children in a parent class
One of possible implementations of such a override is presented in the comment for this blog entry
Quick tip (Flex 4): Goodbye templates – hello mxmlContent
http://www.websector.de/blog/2009/10/02/quick-tip-flex-4-goodbye-templates-hello-mxmlcontent/

Validator Components in Flex3 Air

How to use validator controls like Required validator, integer validator etc in Air application? I tried to use them but I got this error:
Component declarations are not allowed here. (Note: visual children must implement mx.core.IUIComponent)
i have imported the validator like this...
import mx.validators.Validator;
and used like this
<mx:TextArea id="txtQuestCaption" change="txtQuestCaption_change(event)"/>
<mx:Validator id="reqValidator" source="txtQuestCaption">
</mx:Validator>
But i got that above error..
how to use validator in air ?
It seems that this code is nested inside some container tag. Move the <mx:Validator/> tag out of the current position and place it directly within the root mxml tag. Non visual tags like Validator, Style etc should be added as the immediate children of the root mxml tag
<!-- wrong -->
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Canvas>
<mx:TextArea id="txtQuestCaption" change="txtQuestCaption_change(event)"/>
<mx:Validator id="reqValidator" source="txtQuestCaption"/>
</mx:Canvas>
</mx:Panel>
<!-- correct -->
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Canvas>
<mx:TextArea id="txtQuestCaption" change="txtQuestCaption_change(event)"/>
</mx:Canvas>
<mx:Validator id="reqValidator" source="txtQuestCaption"/>
</mx:Panel>

Flex 4: Build a Group with a background

I'm trying to build a simple component extending spark.components.Group to have a background color, more specifically a spark.primitives.Rect component stretched to fill the background.
This is what I've come up with thus far:
<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/halo"
<fx:Metadata>
[DefaultProperty(name="content")]
</fx:Metadata>
<s:Rect id="background" width="100%" height="100%">
<s:fill>
<s:SolidColor color="#990000"/>
</s:fill>
</s:Rect>
<s:Group id="container"/>
<s:filters>
<!-- For good measure ;) -->
<s:DropShadowFilter color="#000000" strength="0.4" blurX="5" blurY="5" distance="2" angle="90"/>
</s:filters>
<fx:Script>
<![CDATA[
public function set content(value:Array):void {
this.container.mxmlContent = value;
}
]]>
</fx:Script>
</s:Group>
Ok, so the logic here basically makes sense, right? All children declared in MXML go to the Group called "container". That is working just fine. However, when I run the example below, the layout is completely fubar.
<s:VGroup>
<!-- This is the component described above -->
<components:MessageContainer id="component" width="100" height="100"/>
<mx:Slider/>
<mx:Slider/>
<mx:ColorPicker/>
</s:VGroup>
This is what it looks like:
Is there something I'm missing here? Maybe a method I need to override?
Weird. I just resorted to making a Skin implementation and applying it to a SkinnableContainer. I was compiling using the Beta 2 release of Flex 4 as well. Very strange indeed.
What build of flex 4 are you using? I just copied your code exactly and the output looks as you would expect it to.
I am running the beta 2 build that was released within the last few weeks. Build 4.0.0.253292. You can upgrade your build if you aren't running the latest, but you can also try to clean the project. It might just be getting confused. Also make sure your browser isn't caching the swf, which sometimes happens when the file size doesn't change dramatically.

Resources