I used this code on Flex 3.5 SDK with Flash Builder 4 inside a function that is being called on creationComplete of the MXML app.
var myButton:Button = new Button;
myButton.label = "test";
addChild(myButton);
Alert.show("Button Created");
It works fine however, when I use it on the same Flash Builder 4 only this time, under Flex 4.0 SDK, nothing's happening. The Alert.show() isn't even showing which means it doesn't even get to that point.
So my question is, what's wrong? Am I missing something?
P.S.
I need to be able to create / remove MXML components on the fly (while the app is running). This is just a test script and I'm failing miserably at achieving what I need.
In Spark you need to use addElement instead of addChild
var b:Button = new Button();
addElement(b);
I'm not sure why your alert isn't working :\
Usually you create the UI in MXML, but in some cases you do need to create UI elements on the fly, and as the other poster mentioned, addElement() is the key with Flex 4 Spark containers.
When adding components to MX containers (from Flex 3), you still use addChild() in Flex 4. You only need to use addElement() when adding to Spark containers.
Of course, Adobe recommends you use the Spark containers when there is a somewhat comparable MX container.
Its better that you do it in the flex way.
<fx:Script>
<![CDATA[
import mx.controls.Alert;
private function alert():void
{
Alert.show("Button added to stage");
}
]]>
</fx:Script>
<s:Button id="myButton" label="test" addedToStage="alert()"/>
You can't add a button using mere addChild in flex. First you need to create an UIComponent and then add the button to the UIComponent. Its a bit different from the flash way.
Related
I hava a problem with flashbuilder:
I have a list with an itemrenderer that renders an image that (should be) draggable.
the rendered image refers to a function that is declared in an actionscript file: dragDrop.as in the folder AS.
the list:
<s:List id="imageList" width="139" height="438"
dataProvider="{xmlListColl}"
itemRenderer="itemRenderer.ImageRenderer"
dragEnabled="true">
</s:List>
the itemrenderer renders this image and refers to the function doDrag:
<mx:Image width="100" height="70" maintainAspectRatio="true"
MouseDownEffect="AS.dragDrop.doDrag(event)"
source="{data.#thumbnailImage}"/>
the function in dragDrop.as:
public function doDrag(event:MouseEvent):void
{
var img:mx.controls.Image = event.currentTarget as mx.controls.Image;
var dragImg:mx.controls.Image = new mx.controls.Image();
dragImg.source = img.source;
var dsource:DragSource = new DragSource();
dsource.addData(img, 'img');
DragManager.doDrag(img, dsource, event, dragImg);
}
but it seems the function is never called...
also parentdocument and outerdocument don't seem to work (if i put the function in the document where the itemrenderer is called)
Please Help!
There's a few issues here, but ultimately, you're not seeing a reference to that method, which means your dragDrop.as file is not including.
Here are a few suggestions:
Replace MouseDownEffect with mouseDown. Instead of causing an effect to occur, you're now listening for the "MouseEvent.MOUSE_DOWN" event to fire. Differences between effects and responding to events are described here and, to quote, "Behaviors let you add animation and motion to your application when some user or programmatic action occurs, where a behavior is a combination of a trigger paired with an effect. A trigger is an action, such as a mouse click on a component ... An effect is a visible or audible change to the target component that occurs over a period of time, measured in milliseconds."
Make sure you're including your dragDrop.as file. Flex 3 vs. Flex 4 handle script tags differently. If you're not including or importing your code, then of course it won't fire.
include vs import is a good question. You can "include" code that's a definition of methods, instances, constants, etc. But you would "import" defined classes for use. Since your method is a public function, does it live within a class? Or is it meant to just live in the script file, in which case you should remove the accessor "public"
If you're looking to implement Drag-and-Drop, I highly recommend NOT re-inventing the wheel and checking out what Adobe has already implemented for components, including dragEnabled='true' and dragMoveEnabled='true'. Check them out here: http://livedocs.adobe.com/flex/3/html/help.html?content=dragdrop_4.html
http://livedocs.adobe.com/flex/3/html/help.html?content=dragdrop_1.html
Here is an example of a Flex 3 script tag:
<mx:Script source="AS/dragDrop.as"/>
Here is an example of a Flex 4 script tag:
<fx:Script source="AS/dragDrop.as"/>
This is an link to the documentation on how to include directly into a <fx:Script> tag the code you'd like: http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf61c8a-7ff4.html
I try to figure out how does focus mechanism work in Flex. Here comes the example of what I mean:
Let's assume that we have a simple web application, which contains custom component that extends Canvas and implements mx.managers.IFocusManagerComponent. This component overrides focusInHandler and focusOutHandler methods and shows some feedback on how they are called (thinner or thicker border). This custom component also contains some Text.
The source of the component is:
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="100" height="100" creationComplete="cc();" implements="mx.managers.IFocusManagerComponent">
<mx:Script>
<![CDATA[
import mx.containers.Canvas;
import mx.controls.Text;
import mx.controls.TextArea;
import mx.core.UIComponent;
import mx.managers.IFocusManagerComponent;
public function cc():void
{
text = new Text;
text.text = "123";
addChild(text);
setStyle("backgroundColor", "0xddddff");
setStyle("borderColor", "0x000000");
setStyle("borderThickness", 1);
setStyle("borderStyle", "solid");
}
private var text:Text;
override protected function focusInHandler(e:FocusEvent):void {
trace("focusInHandler, currFocus: " + focusManager.getFocus());
setStyle("borderThickness", 4);
}
override protected function focusOutHandler(e:FocusEvent):void {
trace("focusOutHandler, currFocus: " + focusManager.getFocus());
setStyle("borderThickness", 1);
}
]]>
</mx:Script>
</mx:Canvas>
Here is the live version (with source view): http://rafalrybacki.com/lab/focus_question/. In the app there is also a TextArea below the Canvas - to ease the focus manipulation when testing.
The questions:
If you click once on a violet canvas it receives focus (focusInHandler is called), then if you click again the focus is lost (focusOutHandler called) - why?
Of you click on a Text the Canvas receives focus (focusInHandler called) and keeps it when being clicked wherever on the area (focusOutHandler nevet called) - why?
Maybe my understanding of the whole focus issue is wrong? Thank you for any suggestions.
With respect,
Rafal
Hey Rafalrybacki. [I'm in a meeting, and can't really spend time on the question but thought I could help with a pointer or two:]
First, the intent of a Canvas is to interact with FocusManager differently than a component that implements IFocusManagerComponent. Canvas implements IFocusManagerContainer and while you can accomplish what you're trying to accomplish by making the container an IFocusManagerComponent, I'd avoid it, simply because I try to do that which I think the flex sdk team intended when using internal components.
What I think they'd intend is for you to listen to the FocusEvent in your container. FocusEvents bubble by default, so you can accomplish most everything you need to with a simple event listener.
Note: Listening to a focusOut can get confusing with components that have multiple uicomponents as children --- i.e. combobox has a UITextField and a Button, so the component has multiple FocusOut and FocusIn events happening from whithin the same component. Your savior will be (I would guess) doing a container.contains() on a focusManger.getFocus() item (casting it etc.) to accurately set your style.
I just blab, so if you need some help beyond this, or would like to know more about why a focusIn or focusOut evt is being dispatched when it is being dispatched -- I'd be happy to slap some code together for you and explain why the type of event is being caught. Your best bet tho' (to fit within flex sdk guidelines) is to use an event listener from within the container, and not fight with a component that is both an IFocusManagerComponent AND an IFocusManagerContainer. Could get messy.
Hope that helps. Best of luck,
Jeremy
I'm absolute newbie in Flash development but anyway I need to do something.
I have a pure AS3 project that plays video from youtube (chromeless player). I need to add some controls to manage this player. I don't know how to do that? If I just add mxml file into the project nothing happens. How to bind this file to as3?
Thanks
Flex components need to have UIComponent parent to function properly. If your player is based on Sprite, controls will not be initialized.
There is a trick to use Flex controls in the Sprite, but only after initialization in Flex Application. If you don't have Application, no luck.
You could use an AS3-only alternative. One library I've used is minimalcomps which offers some simple but effective controls for use in any AS3 project.
You can't use MXML, but nobody stops you to create your own controls if they are simple.
A short and simple example of how to add a button with an image:
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest('http://i1.nyt.com/images/misc/nytlogo379x64.gif'));
function onComplete(event:Event):void
{
var button:Sprite = new Sprite();
button.addChild(event.currentTarget.content);
addChild(button);
button.buttonMode = true;
button.addEventListener(MouseEvent.CLICK, onButtonClick);
}
function onButtonClick(event:MouseEvent):void
{
trace ('click');
}
This would be the most basic version of a button with a loaded bitmap image.
Normally you would like to check for errors as well... what to do if the image is not found, or when you're not allowed to access it.
If you're going to need more then one button you could make a class which accepts an url, so you could just pass the url to the class and the button would be created.
A completely other way to approach this is with an SWC file, you could create the buttons in the Flash IDE and export them as an swc, which you can embed and use in your pure AS3 project.
How can I add an MXML component as a child of the main application using ActionScript. It's not possible to instatiate it, is it? Assuming that behind every mxml file stands an actionscrpt3 class, I tried to import it but id didn't show up.
You'll want to familiarize yourself with the flex component lifecycle: http://msimtiyaz.wordpress.com/flex/adobe-flex-component-instantiation-life-cycle/
It explains the actionscript code behind the mxml components, and it's important to be familiar with, because if you implement your components incorrectly, it can really slow down your application.
Anyway, I think you may be confused about what imports do. Import statements make the code available to use in your code, but it wouldn't create a component. You'd need to create a component the same way you create any object in actionscript, and then you'll need to add that component to the display list to make it show up.
The appropriate place to do this is in the createChildren() function:
override protected function createChildren():void {
super.createChildren();
var myText:Text = new Text();//create a new object
this.addChild(myText);//add it to the display list
}
I have used Flash to make skins, which I import and apply to Flex components.
But how can I create a component in Flash, with properties and methods. And make it able to be added to the displayList in a Flex app?
I installed the Flex component kit for flash. Created my component in flash (it extends MovieClip). Did Command->Convert to flex Component, did File->Published, which gave me a .swc, dropped the .sec file into my Flex project. Now when I create a new var the class "FlashFlexComponentTest" pops up in the new class hint box, so flex sees it. But afterwards I get the error:
Type was not found or was not a
compile-time constant: FlashFlexComponentTest
I feel like I must be missing a step?
Thanks!
UPDATE
I added the .swc via project build path -> add SWC.
I no longer have a compile-time error but I am getting a runtime error:
Type Coercion failed: cannot convert FlashFlexClassTest#9089129 to mx.core.IUIComponent
The base class for all flex components, UIComponent, allows you to add Sprites that don't implement the IUIComponent interface.
An example :
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
creationComplete="init();">
<mx:Script>
<![CDATA[
private function init():void
{
var component:FlashFlexClassTest = new FlashFlexClassTest();
container.addChild(component);
}
]]>
</mx:Script>
<mx:UIComponent id="container" width="100%" height="100%"/>
</mx:Application>
There's a good video tutorial on this at Linda.com by David something. I did a lot of this a year or so ago, and that was the best resource I found. Doesn't cover absolutely every possible angle, but does a great job of covering what you need to know.
I'm guessing there's just some small linkage detail that you're missing. The tutorial should get you straight, if that's the case. It was worth the $20, or whatever, for a monthly subscription for me.
Sorry, that's the best I can do... haven't built Flex components in Flash since last year.
basically there are step what need to do:
open Flash
drag a component you need to stage
right click on it in Library > Export to SWC
put this SWC in your Flash Builder libs folder
There is explanation by Jesse Warden http://jessewarden.com/2011/06/integrating-flash-components-with-flex-revisited.html
Cheers!