Archive for December, 2009

Catching Range Error when trying to use getItemAt for ArrayCollection

If you have ever been doing some work with ArrayCollections, you must have seen Flash Range Error when trying to use getItemAt method on ArrayCollection if there is no entry for the index provided.

For example:

private var myAC:ArrayCollection = new ArrayCollection();
myAC.addItem({key1: 'value1', key2: 'value2', key3: 'value3'});

trace (myAC.getItemAt(0).key1) //returns value1

trace (myAC.getItemAt(1).key1) //you get Range Error: Index '1' specified is out of bounds

So how can we ensure that we don’t get a Range Error when we try to access an index in arraycollection that does not exist. We can use try catch, so we try to getItemAt some index and then we catch if we get an error.

Going back to the previous example

private var myAC:ArrayCollection = new ArrayCollection();
myAC.addItem({key1: 'value1', key2: 'value2', key3: 'value3'});
try {
trace (myAC.getItemAt(0).key1) //returns value1

trace (myAC.getItemAt(1).key1) //will not generate a general error but will go into the catch and trace index is out of bounds
} 
catch (e:RangeError){
	trace('index is out of bounds');
}

This time around we wont get an Range Error, rather after Flash will encounter Range Error it will go into the catch block and execute any code that is written there, in our case, just tracing that index is out of bounds.

I would recommend doing try catch when using getItemAt, because it can quickly happen that we want to access and index that is not in the ArrayCollection.

Happy coding 🙂

Advertisements

, , , , ,

Leave a comment

How to specify line height for Text component in Flex

Yesterday I was doing some coding and I wanted to increase line-height of Text component, and saw that there is no line-height style property in Flex, like there is for example in CSS. So google helped me once again and I wound this article http://blog.flexexamples.com/2008/05/31/setting-the-leading-on-a-text-control-in-flex/.

It states that you use property leading to set line-height (that is the distance from bottom of first row of text to the top of next line of text).

If I have multiline text and want to increase leading or line-height, I can just do the following:

<mx:Text text="Here is a loooong string that will span multiple lines" leading="5" />

Below is an image that shows the difference in Text component if it has leading set to 1 and to 5. (screenshot is taken from blog.flexexamples.com)

Leading = 5 vs. leading = 1

, , ,

Leave a comment

Using stackoverflow.com to get quick answers to programming problems

Couple of days ago I was doing some Flex programming, and one thing bothered me while I was assigning one ArrrayCollection to another one. For example, let’s say we have 2 ArrayCollections caled firstAC and secondAC. firstAC has for instance 10 rows. Now I wanted secondAC to get all the data from firstAC, so I did secondAC = firstAC.

Then whatever I did with secondAC (use addItem or filterFunction) everything would show up in firstAC. Since I didnt quite know what was going on I used stackoverflow.com and posed this question:

Title: Changes to one variable propagates to another

For example I have two ArrayCollection’s – firstAC and secondAC. If I do secondAC = firstAC, and than I make changes to secondAC (prehaps put a filterfunction on it) it somehow propagates to firstAC, would anyone tell me why that happens in Flex or Actionscript 3?

What can I do if I only want secondAC to get all data from firstAC but then when I make changes to secondAC it does not show in firstAC?

Thanxs a bunch for answers! Ladislav

All I had to do is wait a while and answers came in:

Answer nr. 1: phtrivier

When you write secondAC = firstAC, you simply state that secondAC and firstAC are references to the same array collection.

What you want is to clone the first collection (as in, copy all elements one by one).

You should be able to do it with something like :

secondAC = new ArrayCollection();
secondAC.addAll(firstAC);
Answer nr. 2: Christopher W. Allen-Pool

In ECMAScript languages (AS1-3, JavaScript, et al.), when you use

var foo = //some value which is not a String or a Number

what you are really saying is “foo now points to the same object as that other variable.” This means that in this situation, both arrays will be the same value:

var foo:Array = [ 1, 2, 3 ];
foo = bar;
bar.push( 4 );
trace( foo ); // 1, 2, 3, 4

This also works for functions:

var foo:Array = [ 1, 2, 3 ];
adder( foo );
function adder( bar:Array ):void {
    bar.push( 4 );
}

trace( foo ); // 1, 2, 3, 4

and it even works with XML:

var xml:XML = <root><foo/></root>;
var bar:XML = xml;
bar.children()[ 0 ].@bar = 1;
trace( xml.toXMLString() ); // <root><foo bar="1"/></root>

This is called “passing by reference” instead of “passing by value” or “passing by copy”. It means that every time that an item is referenced, each variable will point to the same object.

There are many ways to get around this, and most of them depend on your context. For arrays, my favorite is Array.concat(), which returns a literal clone of the array. This means that anything I do to the returned value will not effect the original in any way. If I’m dealing with XML, however, I will do something like: var xml2:XML = XML( xml.toXMLString() );.

In your case, I would actually recommend that you use:

var secondAC:ArrayCollection = new ArrayCollection( firstAC.source.concat() );

This has the major benefits of not only being faster (it relies on compiled code instead of Flex SDK code and it also does not first instantiate a new array and then re-populate it), but it also has the distinct benefit of being available in older versions of Flex 3’s SDK — it is entirely backwards compatible.

As you can see you can get some really good answers quickly by posting a question on stackoverflow.com. It is nice to see how many people are willing to put in their time and effort to answer a fellow programmer’s question.

Thanx to all for replying on my threads on stackoverflow 🙂

Link to the original post: http://stackoverflow.com/questions/1868431/changes-to-one-variable-propagates-to-another/

, ,

Leave a comment

Wanna sell your website or build a statup?

Last night while I was doing some browsing in the web, I came across an interesting site called flippa.com. The idea behind flippa is that you can try to sell your site or even your business, on the other hand since there are sellers out there you can buy and get a website you like.

Let’s see what flippa says about itself: Flippa: The #1 Marketplace for Buying and Selling Websites and Domains.

Flippa.com

It is a cool idea and just by browsing around you can get a sense of things that people are selling and buying. One interesting section just sold seciton, where you can see projects, webpages and businesses that have been sold most recently.

One other site that I found recently and that I find useful, is startups.com. It is build on the same platform as stackoverflow.com (a site where programmers ask all kinds of questions). On statups.com people post all sorts of questions regarding startups, business, marketing, entrepreneurship and so on. Just by reading through the questions and answers you can gain lot’s of valuable information about the subject of startups. Highly recommended.

Startups.com

, ,

Leave a comment

Adding source code to engineeringtheworld blog

Today while I was doing some work on this blog I saw an announcement from WordPress pointing to this post Better Source Code Posting. It is a short description about how you can easily add sourcecode into wordpress.com blogs with [sourcecode].

In my other worpress.org blogs that I hosted on my servers I used pre and code tags, which on wordpress.com did not work as I would like. That is why all the sourcecode in my posts were images, which is not optimal for readers of this blog, because they cannot easily copy and paste code into their project.

Now that I found out how to add source code, I will change the images I used with acctual source codes.

Leave a comment

Dispatching DataGridEvent to enter ItemEditor in DataGrid

I our previous example we made a custom DataGrid, populated it and add functionality to add new data. When we press the Add new city button in our application the new row is selected, but wouldn’t it be cool if we also entered into the Item Editor of the name of the newly added city? That is something that users would probably expect from our program and since we have to change the name of the city we can save one precious click.

Link to application

When I wanted to do this, I Googled my way on to web page from Adobe that explains what event needs to be dispatched if we want to enter Item Editor of a given row and column in data grid. (DataGridEvent).

There is one event that exactly suites our purpose at that is ITEM_EDIT_BEGINNING, The DataGridEvent.ITEM__EDIT_BEGINNING constant defines the value of the type property of the event object for a itemEditBeginning event, which indicates that the user has prepared to edit an item, for example, by releasing the mouse button over the item.

So in our code we will add just one line of code that will dispatch DataGridEvent.ITEM_EDIT_BEGINNING and with this we will enter into the Item Editor of the newly added city just like we wanted. In add_city() function below dg_cities.selectedIndex = _id; we add the following:

dg_cities.dispatchEvent(new DataGridEvent(DataGridEvent.ITEM_EDIT_BEGINNING, false, false, 1, null, cities.length-1));

So we are dispatching a DataGridEvent, first property is the type of event that we are dispatching (hopefully I am saying this in a right way…), second and third parameters we leave as defaults, which is in both cases false, then we need to tell which coulumn of the DataGrid we want to change (id – 0, city name – 1, population – 2), so we input 1 since we want to change the city name, next parameter is again left as default – null. The last parameter we input is in which row of the column we specified we want to enter Item Editor, and that is the last row of the cities AC.

And that is all you have to do to enter Item Editor of the city name after we add one more city to DataGrid. If we wanted to edit population first we would just change parameter column from 1 to 2 and that would work as well.

private function add_city():void{
				var _id:int = cities.getItemAt(cities.length-1).id;
				_id++;
				cities.addItem({id: _id, city: 'input city', millions:0});
				dg_cities.selectedIndex = _id;
				dg_cities.dispatchEvent(new DataGridEvent(DataGridEvent.ITEM_EDIT_BEGINNING, 
										false, false, 1, null, cities.length-1));
				dg_cities.validateNow();
				dg_cities.scrollToIndex(_id);
			}

, , ,

2 Comments

Using Item Editors in DataGrid, adding new data to DataGrid

In this example we are going to explore how to use editable dataGrids with itemEditor’s. We will also see how to add values to the DataGrid.

The application that we will build here can be found here.

Our application consists of Label, Button and DataGrid. In the DataGrid we are showing couple of US cities, the button gives us possibility to add new cities to our DataGrid.

Our application MXML tag has once again calls init() when application is initialized, there we add couple of items to ArrayCollection cities.
ArrayCollection cities has 3 fields id, city and millions (referring to population of a city).

	
private function init():void{
				cities.addItem({id:1, city: 'New York', short: 'NY', millions: 8});
				cities.addItem({id:2, city: 'Miami', short: 'MI', millions: 1});
				cities.addItem({id:3, city: 'Los Angeles', short: 'LA', millions: 4});
				cities.addItem({id:4, city: 'San Francisco', short: 'SF', millions: 1});
			}

Next lets look at our DataGrid MXML code:

<mx:DataGrid id="dg_cities" dataProvider="{cities}" editable="true">
		<mx:columns>
			<mx:DataGridColumn headerText="id" editable="false" dataField="id"/>
			<mx:DataGridColumn headerText="City" dataField="city"/>
			<mx:DataGridColumn headerText="Population in millions" dataField="millions" 
				itemEditor="mx.controls.NumericStepper" editorDataField="value" width="150"/>
		</mx:columns>
	</mx:DataGrid>

We set the dataProvider of DataGrid to cities, notice the usage of curly braces, which means that we want ActionScript 3 code to be executed within those braces. In our case just point to cities AC as dataProvider. Next we also set editable tag to true, which will enable us to modify data in DataGrid.

Since we dont wont Flex to build DataGrid for us based on it’s dataProvider we use mx:colums and mx:DataGridColumn to specify each of the 3 columns we want to show.

For column id, we want the header text to read id, that is why we put headerText=”id”, we also do not want this column to be editable, thus editable is set to false. We also have to tell DataGrid which field from cities AC we want to show in the first column, we do this by dataField=”id”.

Second column is preety much the same, we want it to be editable don’t have to use editable=”true” since this is default behavior for any DataGrid that has editable set to true. HeaderText is City and dataField is city.

For the third column we will use a itemEditor. In this case since we have population in millions of people we use Flex component NumericStepper. We can do this by itemEditor=”mx.controls.NumericStepper”. Since we are using custom itemEditor, we have to specify what data should DataGrid take from itemEditor. Since the value in NumericStepper is stored in value we put editorDataField=”value”.

Our button has a click event that calls function add_city(). Let’s explore what happens there. First we stor the last id from cities AC into variable _id. Next we increase _id by one with _id++. (in the source code below _id is casted as Number, where we should use int).
We than addItem to cities AC, select the last row in DataGrid (which is the row we just added), with dg_cities.selectedIndex = _id.

The next two lines of code ensure that when the DataGrid will become scrolable, it will automatically scroll to the last row in DatGrid. I belive that we have to use dg_cities.validateNow(), before we use dg_cities.scrollToIndex(_id), because we just added a new row to AC and we want DataGrid to refresh itself before we tell it to scroll to the last row.

Next time we will look at how to dispatch Event so that when we click Add new city button we will directly go into city itemEditor for the newly added city. This is something users are accustomed to and it saves us 1 click 🙂 (added in the next post)

Application Source Code

, ,

Leave a comment