views:

2269

answers:

7

Is it possible to use the Flex Framework and Components, without using MXML? I know ActionScript pretty decently, and don't feel like messing around with some new XML language just to get some simple UI in there. Can anyone provide an example consisting of an .as file which can be compiled (ideally via FlashDevelop, though just telling how to do it with the Flex SDK is ok too) and uses the Flex Framework? For example, just showing a Flex button that pops open an Alert would be perfect.

If it's not possible, can someone provide a minimal MXML file which will bootstrap a custom AS class which then has access to the Flex SDK?

A: 

Yes it is possible to use flex without using mxml. Fot lots of help, advice - and a really powerful, yet free AS3 IDE - on working with flash 9+, flex and AS3, checkout http://www.flashdevelop.org/community/.

David Arno
Hmm...I was looking more for an answer that actually says how to do it, not just a simple "Yes it's possible, go ask someone else." I'll try asking on their forum though, didn't see this question answered exactly from my searches.
davr
+1  A: 

Yes, you just need to include the flex swc in your classpath. You can find flex.swc in the flex sdk in frameoworks/lib/flex.swc

edit: One more thing: if you're using Flex Builder you can simply create a new ActionScript project, which will essentially do the same as above.

Antti
It doesn't quite work. You get various errors when you actually try to use Flex components like Button or DataGrid etc
davr
+9  A: 

This is a very simple app that does only the basic bootstrapping in MXML. This is the MXML:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete()">
  <mx:Script source="Script.as" />
</mx:Application>

This is the Script.as:

import mx.controls.Button;
import flash.events.MouseEvent;
import mx.controls.Alert;
import mx.core.Application;

private function onCreationComplete() : void {
  var button : Button = new Button();
  button.label = "Click me";
  button.addEventListener(MouseEvent.CLICK, function(e : MouseEvent) : void {
    Alert.show("Clicked");
  });

  Application.application.addChild(button);
}
Borek
This one's a little more complex than Theo's, but it actually works. I'm going to accept your answer for now, but I might change it later if he fixes his.
davr
This is nice but unfortunately in FlashDevelop there is no code completion on e.g. "button". Any way to enable that?
Edward Tanguay
+6  A: 

NOTE: The below answer will not actually work unless you initialize the Flex library first. There is a lot of code involved to do that. See the comments below, or other answers for more details.


The main class doesn't even have to be in MXML, just create a class that inherits from mx.core.Application (which is what an MXML class with a <mx:Application> root node is compiled as anyway):

package {

  import mx.core.Application;


  public class MyFancyApplication extends Application {

    // do whatever you want here

  }

}

Also, any ActionScript code compiled with the mxmlc compiler -- or even the Flash CS3 authoring tool -- can use the Flex classes, it's just a matter of making them available in the classpath (refering to the framework SWC when using mxmlc or pointing to a folder containing the source when using either). Unless the document class inherits from mx.core.Application you might run in to some trouble, though, since some things in the framework assume that this is the case.

Theo
Hmm...I went to actually try this, and a simple "Hello World" gets tons of runtime errors. Is there some kind of initialization I need to do, or other specific classes I need to include?
davr
It's very easy to find out, just add -keep-generated-actionscript to the compiler flags and compile a MXML class that inherits from Application. The compiler creates a directory called "generated" where you can find the generated ActionScript code. It's a bit more complicated than the above, true.
Theo
+4  A: 

I did a simple bootstrap similar to Borek (see below). I would love to get rid of the mxml file, but if I don't have it, I don't get any of the standard themes that come with Flex (haloclassic.swc, etc). Does anybody know how to do what Theo suggests and still have the standard themes applied?

Here's my simplified bootstrapping method:

main.mxml

<?xml version="1.0" encoding="utf-8"?>
<custom:ApplicationClass xmlns:custom="components.*"/>

ApplicationClass.as

package components {
    import mx.core.Application;
    import mx.events.FlexEvent;
    import flash.events.MouseEvent;
    import mx.controls.Alert;
    import mx.controls.Button;

    public class ApplicationClass extends Application {
        public function ApplicationClass () {
            addEventListener (FlexEvent.CREATION_COMPLETE, handleComplete);
        }
        private function handleComplete( event : FlexEvent ) : void {
            var button : Button = new Button();
            button.label = "My favorite button";
            button.styleName="halo"
            button.addEventListener(MouseEvent.CLICK, handleClick);
            addChild( button );
        }
        private function handleClick(e:MouseEvent):void {
            Alert.show("You clicked on the button!", "Clickity");
        }
    }
}

Here are the necessary updates to use it with Flex 4:

main.mxml

<?xml version="1.0" encoding="utf-8"?>
<local:MyApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:local="components.*" />

MyApplication.as

package components {
    import flash.events.MouseEvent;
    import mx.controls.Alert;
    import mx.events.FlexEvent;
    import spark.components.Application;
    import spark.components.Button;

    public class MyApplication extends Application {
        public function MyApplication() {
              addEventListener(FlexEvent.CREATION_COMPLETE, creationHandler);
        }
        private function creationHandler(e:FlexEvent):void {
            var button : Button = new Button();
            button.label = "My favorite button";
            button.styleName="halo"
            button.addEventListener(MouseEvent.CLICK, handleClick);
            addElement( button );
        }
        private function handleClick(e:MouseEvent):void {
            Alert.show("You clicked it!", "Clickity!");
        }
    }
}
jgormley
Cool, this looks like about as minimal as you can get it, mxml-wise. Accepting your answer since it's almost pure AS code.
davr
Beautiful, thanks. Using FlashDevelop you even have rich code-completion on objects such as "button". Nice. This didn't work in Borek's example.
Edward Tanguay
Updated to include example of the code needed for Flex 4.
davr
+3  A: 

A complete code snippet that allows to invoke some of the most important Flex components by ActionScript only can be found here.

A: 

I can't run jgormley's example without errors. When I click on the Button I get this Error Message:

ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller. at flash.display::DisplayObjectContainer/getChildIndex() at mx.managers::SystemManager/getChildIndex()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:1665] at mx.managers.systemClasses::ActiveWindowManager/mouseDownHandler()[E:\dev\4.0.0\frameworks\projects\framework\src\mx\managers\systemClasses\ActiveWindowManager.as:437]

I'm using FlashBuilder 4 with the 4.0 SDK How can I solve this?

Laurid Meyer
This should have been posted as a comment, not as an answer. You are using Flex 4, this example was written for Flex 3, so there are minor changes needed. I added info to his example showing how to use it with Flex 4 (Tested working with FlashDevelop and Flex 4.1.0 SDK)
davr