could not be able to work with the SplitViewNavigator container - sqlite

I want to make an App using SplitViewNavigator container which contains List of cities in left view and Detail about the city in right view, In right view there is a text input through I get Name of city and store in a SQLite Database, and that name should be added to list in left view from SQLite Database I got started with flowing code in Main.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
applicationDPI="160"
initialize="application1_initializeHandler(event)">
<fx:Script>
<![CDATA[
import model.DataModel;
import mx.events.FlexEvent;
import valueobject.CityValueObject;
import utillities.CityUtils;
public var sqlConnection:SQLConnection;
protected var statement:SQLStatement;
protected function application1_initializeHandler(event:FlexEvent):void
{
sqlConnection = new SQLConnection();
sqlConnection.open(File.applicationStorageDirectory.resolvePath("cityDB.db"), SQLMode.CREATE);
statement.sqlConnection = sqlConnection; // Here error occurs saying that Error #1009: Cannot access a property or method of a null object reference.
statement.text = "CREATE TABLE IF NOT EXISTS CITYNAME (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"nameofcity TEXT)";
statement.execute();
DataModel.getInstance().connection = sqlConnection;
CityUtils.getAllCities();
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:SplitViewNavigator id="svn" width="100%" height="100%">
<s:ViewNavigator width="30%" height="100%" id="list_of_cities" firstView="views.ListOfCities"/>
<s:ViewNavigator width="70%" height="100%" id="display_contents" firstView="views.DisplayContents"/>
</s:SplitViewNavigator>
My model.DataModel is an action script class:
package model
{
import flash.data.SQLConnection;
import mx.collections.ArrayCollection;
[Bindable]
public class DataModel
{
public var connection:SQLConnection;
public var cityList:ArrayCollection = new ArrayCollection();
public var logs:String="Application Logs........\n";
public static var _instance:DataModel;
public function DataModel()
{
}
public static function getInstance():DataModel
{
if(_instance == null)
{
_instance = new DataModel();
}
return _instance;
}
}
}
My valueobject.CityValueObject class is:
package valueobject
{
[Bindable]
public class CityValueObject
{
public var id:uint;
public var nameofcity:String;
}}
And My uttillities.CityUtils class is ::
package utillities
{
import flash.data.SQLResult;
import flash.data.SQLStatement;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.net.URLRequest;
import flash.utils.ByteArray;
import model.DataModel;
import mx.collections.Sort;
import mx.collections.SortField;
import valueobject.CityValueObject;
public class CityUtils
{
public static function getAllCities():void
{
var contactListStatement:SQLStatement = new SQLStatement();
contactListStatement.sqlConnection = DataModel.getInstance().connection;
contactListStatement.text = "SELECT * FROM CITYNAME";
contactListStatement.execute();
var result:SQLResult = contactListStatement.getResult();
if( result.data!=null)
{
DataModel.getInstance().cityList.removeAll();
for(var count:uint=0;count<result.data.length;count++)
{
var cityVO:CityValueObject = new CityValueObject();
cityVO.id = result.data[count].id;
cityVO.nameofcity = result.data[count].city;
DataModel.getInstance().cityList.addItem(cityVO);
}
}
sortData();
}
public static function sortData():void
{
var dataSortField:SortField = new SortField();
dataSortField.name = "cityName";
dataSortField.numeric = false;
/* Create the Sort object and add the SortField object created earlier to the array of fields to sort on. */
var numericDataSort:Sort = new Sort();
numericDataSort.fields = [dataSortField];
/* Set the ArrayCollection object's sort property to our custom sort, and refresh the ArrayCollection. */
DataModel.getInstance().cityList.sort = numericDataSort;
DataModel.getInstance().cityList.refresh();
}
public static function updateLog(newLog:String):void
{
DataModel.getInstance().logs += new Date().time+" :-> "+newLog+"\n";
}
}
}
My left containing list of cities is :
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Cities"
>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import model.DataModel;
import mx.collections.ArrayCollection;
import mx.events.FlexEvent;
import mx.events.IndexChangedEvent;
import spark.components.SplitViewNavigator;
import spark.components.ViewNavigator;
import spark.transitions.ViewTransitionBase;
protected function myList_changeHandler():void {
// Create a reference to the SplitViewNavigator.
var splitNavigator:SplitViewNavigator = navigator.parentNavigator as SplitViewNavigator;
// Create a reference to the ViewNavigator for the Detail frame.
var detailNavigator:ViewNavigator = splitNavigator.getViewNavigatorAt(1) as ViewNavigator;
detailNavigator.transitionsEnabled = false;
// Change the view of the Detail frame based on the selected List item.
detailNavigator.pushView(DisplayContents, list_of_cities.selectedItem);
}
]]>
</fx:Script>
<s:VGroup width="100%" height="100%">
<s:List id="list_of_cities" height="100%" width="100%" change="myList_changeHandler();"
dataProvider="{DataModel.getInstance().cityList}" labelField="nameofcity">
</s:List>
</s:VGroup>
and in last my Display Detail about city is simply like this :
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" title="Detail About City"
>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:actionContent>
<s:CalloutButton id="add_call_out_button" label="Add City" verticalPosition="after"
icon="#Embed('assets/add.png')" calloutDestructionPolicy="never">
<!-- layout the callout content here -->
<s:calloutLayout>
<s:VerticalLayout paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10" horizontalAlign="center" gap="5"/>
</s:calloutLayout>
<s:calloutContent>
<s:TextInput id="city_name_input" prompt="Enter City Name" text="Sydney"/>
<s:HGroup gap="40">
<s:Button id="add_city_name" label="Add City" width="150" height="40" click="add_city_name_clickHandler()"/>
<s:CheckBox id="preferred_cbox" label="Preferred" height="40" />
</s:HGroup>
</s:calloutContent>
</s:CalloutButton>
<s:Button id="remove_city_name" label="Remove" width="120" height="40"
click="remove_city_name_clickHandler()" icon="#Embed('assets/delete.png')"/>
</s:actionContent>
<s:Label id="nameSomeThing" text="{data.Description}"/>
<fx:Script>
<![CDATA[
import model.DataModel;
import spark.components.SplitViewNavigator;
import spark.components.ViewNavigator;
protected function add_city_name_clickHandler():void
{
var sqlStatement:SQLStatement = new SQLStatement();
sqlStatement.sqlConnection = DataModel.getInstance().connection;
sqlStatement.text = "INSERT INTO CITYNAME (nameofcity)" +
"VALUES(:nameofcity)";
sqlStatement.parameters[":nameofcity"] = city_name_input.text;
sqlStatement.execute();
var splitNavigator:SplitViewNavigator = navigator.parentNavigator as SplitViewNavigator;
// Create a reference to the ViewNavigator for the Detail frame.
var detailNavigator:ViewNavigator = splitNavigator.getViewNavigatorAt(1) as ViewNavigator;
detailNavigator.transitionsEnabled = false;
// Change the view of the Detail frame based on the selected List item.
detailNavigator.popToFirstView();
}
protected function remove_city_name_clickHandler():void
{
// TODO Auto-generated method stub
}
]]>
</fx:Script>
the above view(Display Detail) is still in development but at this stage I was Trying to add City Name to list of cities by getting name from city name input text input but at:
statement.sqlConnection = sqlConnection; // Here error occurs saying that Error #1009: Cannot access a property or method of a null object reference.
Iget that error and not be able to go ahead.
Can any one please give me the way to solve my this problem by my code givien above or suggest me an other way to meet my needs by this App Thanks in Advance...

As the error message says, statement is null.
I don't see any code that would initialize it.
You need:
statement = new SQLStament();
(And I don't see any reason why this variable would need to be outside the application1_initializeHandler function.)

Related

Flex 4 Itemrenderer for List

I just started working with Flex. I know it's pathetic but it's a long story.
Now, the problem I am facing is that I have a list component which has a dataprovider on it. What I would like to do is when an item on the list is clicked I would like to have a check sign right next to the label.
Below is the component:
<s:List id="tabList" width="100%"
borderVisible="false" click="tabList_clickHandler(event)"
selectedIndex="{this.hostComponent.selectedIndex}"
itemRenderer="MultiTabListRenderer" />
Below is the Itemrenderer code:
protected function AddCheck_clickHandler(event:MouseEvent):void {
// TODO Auto-generated method stub
var checkLabel:Label;
checkLabel = new Label();
checkLabel.text = "checkMark";
var e: ItemClickEvent = new ItemClickEvent(ItemClickEvent.ITEM_CLICK, true);
e.item = data;
e.index = itemIndex;
dispatchEvent(e);
this.checkRectGroup.addElementAt(checkLabel, e.index);
}
<s:Label id="customMultitabList" text="{data.label}"
left="10" right="0" top="6" bottom="6" click="AddCheck_clickHandler(event)"/>
My code inside the function is wrong which is mainly due to the fact that I do not understand each and everything in flex. I am not in a mood to learn the language in detail because it's not a long term work for me. Also, in the renderer file when I use s:List instead of s:label I do not see the labels anymore. Of course I replace the attribute text with dataprovider={data.selectedItem}.
One way to approach this is to add a field to the objects in your dataProvider that tracks whether or not the item has been selected.
Then, in your item renderer, you inspect this field and decide whether or not to display the checkmark. Here's a working example app and renderer:
Application:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:local="*"
creationComplete="application1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;
import mx.events.FlexEvent;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;
private var collection:ArrayCollection;
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
collection = new ArrayCollection([
{ label: 1, selected: false },
{ label: 2, selected: false },
{ label: 3, selected: false }]);
listbert.dataProvider=collection;
}
protected function listbert_clickHandler(event:MouseEvent):void
{
var index:int = listbert.selectedIndex;
var item:Object = listbert.selectedItem;
item.selected = !item.selected;
// Create these events because the items in the ArrayCollection
// are generic objects. It shouldn't be necessary if items in
// your collection are a Class that extends EventDispatcher
// see ArrayList::startTrackUpdates()
var e:PropertyChangeEvent = new PropertyChangeEvent(
PropertyChangeEvent.PROPERTY_CHANGE, false,false,
PropertyChangeEventKind.UPDATE, 'selected', !item.selected,
item.selected, item);
collection.dispatchEvent(new CollectionEvent(
CollectionEvent.COLLECTION_CHANGE, false,false,
CollectionEventKind.UPDATE, index, index, [e]));
}
]]>
</fx:Script>
<s:List id="listbert" click="listbert_clickHandler(event)" itemRenderer="TestRenderer"/>
</s:Application>
Item Renderer:
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark" >
<fx:Script>
<![CDATA[
override public function set data(value:Object):void
{
super.data = value;
labelDisplay.text = value.label;
if (value.selected)
checkMarkLabel.text = "✓";
else
checkMarkLabel.text = "";
}
]]>
</fx:Script>
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<s:Label id="labelDisplay" />
<s:Label id="checkMarkLabel" />
</s:ItemRenderer>

Display an alert which cannot be closed by user, closes automatically on event

I have a Flex application which sends a query to a database when an user clicks a button. Since the query might be heavy, and can take up to a minute, I want to display an alert, which will close only after an event comes back from the database (user won't be able to close it himself). Is it possible in Flex? How do I do that?
I have functions sendQuery() and dataEventHandler(). I think I need to put code in sendQuery() to display the alert and in dataEventHandler() to close it after data comes from the DB, but how do I make the alert "unclosable" by the user?
The built in Flex Alert class will always have some type of close button.
However, there is no reason you can't create your own component; and then open and close it using the PopUpManager.
Following code may help you… (One of the solution...)
You can find I have made Solution 1 and Solution 2… You can use any one of it and third solution is to create your own Custom Component.
Please find below code…. You can use below logic to solve your problem..
Use Timer to check if data received or you can dispatch custom event and call updateAlertPosition function.
Hope it may help: -
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"
>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.CloseEvent;
import mx.managers.PopUpManager;
private var minuteTimer:Timer;
private var alert:Alert;
private var displayInitialText:String = "Data Not Received, Please wait....";
private var displayDataReveivedText:String = "Data Received...";
private function timerInit():void
{
//Logic to check if data Received.
minuteTimer = new Timer(3000);
minuteTimer.addEventListener(TimerEvent.TIMER, updateAlertPosition);
minuteTimer.start();
}
private function updateAlertPosition(event:Event = null):void {
minuteTimer.stop();
//Solution 1
//add your flag here if y you want to check if data is received or not
//if(Data Received)
alert.mx_internal::alertForm.mx_internal::buttons[0].enabled = true;
alert.mx_internal::alertForm.mx_internal::buttons[1].enabled = true;
alert.mx_internal::alertForm.mx_internal::textField.text = displayDataReveivedText;
//Solution 2
//alert.enabled = true;
//If you want to remove it automatically
//closeAutomatically();
}
private function closeAutomatically():void
{
PopUpManager.removePopUp(alert);
}
private function clickHandler():void
{
//Start Timer
timerInit();
//Solution 1
alert = Alert.show(displayInitialText, "Alert", Alert.OK|Alert.CANCEL,this,alertCloseHandler);
alert.mx_internal::alertForm.mx_internal::buttons[0].enabled = false;
alert.mx_internal::alertForm.mx_internal::buttons[1].enabled = false;
//Solution 2
//alert.enabled = false;
}
private function alertCloseHandler(event:CloseEvent):void
{
if(event.detail == Alert.CANCEL)
{
//Some Code on close
}
else
{
//Some Code on OK
}
}
]]>
</fx:Script>
<s:Button label="Show Alert" x="100" y="100" click="clickHandler()"/>
</s:Application>
make a 0-0.2 alpha shape what covers the whole application (probably you'll want to listen for resizeevents), and add a custom panel to the middle of it, with the message.
As an idea you can create a custom alert then:
Show Alert
Disable Application.
Hide Alert.
Enable Application.
An alert example:
<?xml version="1.0" encoding="utf-8"?>
<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/mx" width="400" height="300"
creationComplete="onCreationComplete(event)">
<s:Rect>
<s:fill>
<s:SolidColor color="0xFFFFFF"/>
</s:fill>
<s:stroke>
<s:SolidColorStroke />
</s:stroke>
</s:Rect>
<s:Label text="Please Wait..."/>
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
public static function show():void
{
PopUpManager.createPopUp(FlexGlobals.topLevelApplication);
}
public static function hide():void
{
PopUpManager.removePopUp(this);
FlexGlobals.topLevelApplication.enabled = true;
}
protected function onCreationComplete(event:FlexEvent):void
{
PopUpManager.centerPopUp(this);
FlexGlobals.topLevelApplication.enabled = false;
}
]]>
</fx:Script>
</s:Group>
Usage:
YourAlert.show();
YourAlert.hide();
#Alex, I used your code but modify it a bit, because there was some errors:
<?xml version="1.0" encoding="utf-8"?>
<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/mx"
creationComplete="creationCompleteHandler()" width="100%" height="100%">
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.core.UIComponent;
import mx.managers.PopUpManager;
///////////////////////////////////////
//// public functions - my group is ImageViewer.mxml component
public static function show():ImageViewer {
return PopUpManager.createPopUp(FlexGlobals.topLevelApplication as DisplayObject, ImageViewer) as ImageViewer;
}
public function hide():void {
PopUpManager.removePopUp(this);
FlexGlobals.topLevelApplication.enabled = true;
}
////////////////////////////
//// component events
private function creationCompleteHandler():void {
PopUpManager.centerPopUp(this);
FlexGlobals.topLevelApplication.enabled = false;
}
]]>
</fx:Script>
</s:Group>
And call it like:
var imageviewer:ImageViewer = ImageViewer.show();
//imageviewer.imageURL = _value_dto.value;

Flex4-How can i get selected image(MouseClick Image)from Array Collection using DataGroup

Gallery in DataGroup, How can i Call selected image(MouseClick Image) this is my Sample code
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.managers.PopUpManager;
import spark.components.Image;
import spark.components.TitleWindow;
[Bindable]
private var myArray:ArrayCollection= new ArrayCollection([
{image:'Assets/images/best_01.jpg'},
{image:'Assets/images/best_02.jpg'},
{image:'Assets/images/best_03.jpg'},
{image:'Assets/images/best_04.jpg'}]);
private function imageClickHandler(event:MouseEvent):void {
var imgCount:Number=0;
var image:Image= new Image();
PopUpManager.addPopUp(image,this,true);
image.source=myArray.getItemAt(imgCount).image;
}
]]>
</fx:Script>
<s:DataGroup id="dg" itemRenderer="com.ItemRenderForHorizontallist"
dataProvider="{myArray}"
verticalCenter="0"
horizontalCenter="0"
click="imageClickHandler(event)">
<s:layout >
<s:TileLayout horizontalGap="20" verticalGap="20" columnWidth="180" />
</s:layout>
</s:DataGroup>
this code work but i want selected image(MouseClick Image) any one help me ............ thanks*
You're using imgCount to access the index of your ArrayCollection; however, you always set it to 0.
You could change s:DataGroup to s:List, then use the selectedItem property in your click handler:
image.source = dg.selectedItem["image"];

Issue with both red and blue colors with validator and errorString of textinput

I'm facing a strange issue with flex and validator.
Here is the code:
TestMain.xml
<?xml version="1.0" encoding="utf-8"?>
<s:Application 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:Script>
<![CDATA[
import mx.controls.Alert;
import mx.validators.StringValidator;
import utils.ValidableProperty;
[Bindable] public var nameID:ValidableProperty;
public function start():void {
var nameIDValidator:StringValidator = new StringValidator();
nameIDValidator.required = true;
nameIDValidator.maxLength = 35;
nameID = new ValidableProperty(nameIDValidator);
nameID.validate();
}
]]>
</fx:Script>
<s:applicationComplete>
start();
</s:applicationComplete>
<s:minHeight>600</s:minHeight>
<s:minWidth>955</s:minWidth>
<mx:Form color="0x323232" paddingTop="0">
<s:Label text="See strange behavior of errorString during validator operation with validate."/>
<mx:FormItem label="Name">
<mx:TextInput id="nameInput" width="300" errorString="#{nameID.errorMessage}" text="#{nameID.value}"/>
</mx:FormItem>
</mx:Form>
ValidableProperty.as
package utils
{
import flash.events.EventDispatcher;
import mx.events.PropertyChangeEvent;
import mx.events.ValidationResultEvent;
import mx.validators.Validator;
public class ValidableProperty extends EventDispatcher
{
[Bindable]
public var value:Object;
private var validator:Validator;
[Bindable]
public var isValid:Boolean;
[Bindable]
public var errorMessage:String;
private var statusChangeHandler:Function;
public function ValidableProperty(validator:Validator, statusChangeHandler:Function=null,
target:IEventDispatcher=null) {
super(target);
this.validator = validator;
this.statusChangeHandler = statusChangeHandler;
this.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE, propertyChangeHandler);
}
private function propertyChangeHandler(evt:PropertyChangeEvent):void {
if (evt.property == "value") {
this.validate();
}
}
public function validate():void {
var result:ValidationResultEvent = this.validator.validate(this.value);
this.isValid = (result.type == ValidationResultEvent.VALID);
if (isValid) {
this.errorMessage = null;
}
else {
this.errorMessage = result.message;
}
if (statusChangeHandler != null)
statusChangeHandler();
}
public function set required(required:Boolean):void {
if (validator == null)
return;
validator.required = required;
}
}
}
When you execute this simple code, when writing a value, for example "A", the errorMessage value "this field is required" will disappear but the red color on the inputtext border will still be there with the blue color.
When deleting the A value, this time the blue color will be there with the red one (cannot reproduce all the time) and the error message "this field is required".
What am I missing here? Is it a bug in flex? We cannot have both of red and blue colors on the textinput border.
I am using Eclipse with Flex SDK 4.5.0 (build 20967)
This is not a bug in Flex. This is a bug with how you're coding it all. If you were to follow the example in the documentation, it would work.
<?xml version="1.0" encoding="utf-8"?>
<!-- Simple example to demonstrate StringValidator. -->
<s:Application 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>
<mx:StringValidator source="{nameInput}" property="text"
tooShortError="This string is shorter than the minimum length of 4. "
tooLongError="This string is longer than the maximum allowed length of 35."
minLength="4" maxLength="35"/>
</fx:Declarations>
<s:Form>
<s:FormItem label="Name">
<s:TextInput id="nameInput" width="300" text="{nameID.value}"/>
</s:FormItem>
</s:Form>
</s:Application>
I finally resolve this. I was using mx:TextInput instead of s:TextInput. Thanks J_A_X for your suggestion !

Flex / ActionScript3 - Object Attribute / Variable null

If I execute the code below in FlashBuilder, I get the following error (I translate it)
TypeError: Error #1009: Access to an Attribute or Method of an null-Object is not possible.
at components::NumDisplay()[\src\components\NumDisplay.mxml:39]
This line in NumDisplay.mxml is the problem:
[Bindable]
public var oneled_top:OneDisplay = new OneDisplay(numberData.led_top);
If i change it from the above to:
[Bindable]
public var oneled_top:OneDisplay = new OneDisplay(1);
It is working, because I send a real Number.
So how can I access the value from numberData.led_top?
If I test the access in the samefile NumDisplay.mxml with the line
<s:Label text="{numberData.led_top}" color="#FF0000">
</s:Label>
it accesses the value, the same as if I put it in my component
<components:oneLedDisplay showData="{numberData.led_top}" x="10" y="10" />
I don't get it after searching a couple of hours...
Thanks in advance.
My main method tasachenrechner.mxml:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="600" minHeight="500" xmlns:components="components.*">
<fx:Script>
<![CDATA[
import components.NumberDisplay;
[Bindable]
protected var firstNumber:NumberDisplay = new NumberDisplay(1);
[Bindable]
protected var secondNumber:NumberDisplay = new NumberDisplay(2);
]]>
</fx:Script>
<components:NumDisplay
numberData="{firstNumber}"
x="10"
y="20"/>
<components:NumDisplay
numberData="{secondNumber}"
x="73"
y="20"/>
</s:Application>
My AS-Class NumberDisplay.as:
package components
{
import flash.display.DisplayObject;
[Bindable]
public class NumberDisplay
{
public var num:Number;
public var led_top:Number=0;
public var led_r1:Number=0;
public var led_r2:Number=0;
public var led_middle:Number=0;
public var led_l1:Number=0;
public var led_l2:Number=0;
public var led_bottom:Number=0;
public function NumberDisplay(num:Number)
{
this.num = num;
switch(this.num)
{
case 0:
trace("ZERo");
break;
case 1:
led_top = 1;
led_r1 = 1;
led_r2 = 1
trace("EINS" + led_top + " num:" + num);
break;
//[... some more cases]
default:
break;
}
}
}
}
My NumDisplay.mxml:
<?xml version="1.0" encoding="utf-8"?>
<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/mx" width="45" height="59"
xmlns:components="components.*">
<fx:Style>
#namespace s "library://ns.adobe.com/flex/spark";
#namespace mx "library://ns.adobe.com/flex/mx";
#namespace components "components.*";
</fx:Style>
<fx:Script>
<![CDATA[
import components.NumberDisplay;
import components.OneDisplay;
[Bindable]
public var numberData:NumberDisplay;
[Bindable]
public var oneled_top:OneDisplay = new OneDisplay(numberData.led_top);
// some more init calls of data-objects same type
]]>
</fx:Script>
<s:Label text="{numberData.led_top}" color="#FF0000">
</s:Label>
<components:oneLedDisplay showData="{oneled_top}" x="10" y="10" />
// some more objects of same type
</s:Group>
My AS-Class OneDisplay.as:
package components
{
import flash.display.DisplayObject;
public class OneDisplay
{
[Bindable]
public var show:Number;
[Bindable]
public var value:Number=0;
public function OneDisplay(show:Number)
{
this.show = show;
switch(this.show)
{
case 0:
value = 0.3;
trace(value);
break;
case 1:
value = 1.0;
trace(value);
break;
}
}
}
}
My oneLedDisplay.mxml:
<?xml version="1.0" encoding="utf-8"?>
<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/mx">
<fx:Script>
<![CDATA[
import components.OneDisplay;
[Bindable]
public var showData:OneDisplay;
]]>
</fx:Script>
<s:Rect id="stroke" width="40" height="6" alpha="{showData.value}">
<s:fill>
<s:SolidColor color="#000000"/>
</s:fill>
</s:Rect>
<s:Label text="{showData.value}" color="#FF0000">
</s:Label>
</s:Group>
Remember that you are not only assigning a value, but declaring the member variable oneled_top. At that point, you cannot access numberData because it has not been instantiated (there is no call to new NumberData()! You have to find a way to make your call to new OneDisplay (numberData.led_top) at a later time, when there actually is a value to access.
You provided lots of code which I don't want to reverse engineer.
The answer is that oneled_top is being initialized before numberData. You have no control over initialization of variables when using MXML.
Set default values in the commitProperties() method, or if oneled_Top is supposed to be a skin part, set the default values in the PartAdded method.
You'll benefit from reading up on the Component Lifecycle.
You can use BindingUtils.bindSetter() to detect changes to numberData and then initialize oneled_top
BindingUtils.bindSetter(_setOneLabel_top, this, "numberData");
and setter:
function _setOneLabel_top(disp:NumberDisplay):void
{
/* if(this.oneled_top == null) */
this.oneled_top = new OneDisplay(disp.led_top);
}
But I think, that u're using [Bindable] where you shouldn't have to need it.

Resources