Browsing articles in "Flex"
Jan
23

Parsing Tweets with the TwitterString Class

While building a little Twitter aggregator for an upcoming conference, I found myself in need of a set of methods to create hyperlinks from three distinct elements that can be included within a tweet; links, usernames, and hashtags.

I was able to find regular expressions to do all the heavy lifting from various sources on the Web and have created a class which pretty much does all the processing with one method call. Here’s an example of the thing working, followed by example code, and the class itself.

Example SWF

This movie requires Flash Player 8


Example MXML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?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" 
			   creationComplete="init()" width="300" height="100" 
			   backgroundColor="#1E1E1E" preloaderBaseColor="#989898">
 
	<fx:Script>
		<![CDATA[
			import flashx.textLayout.elements.Configuration;
			import flashx.textLayout.elements.TextFlow;
			import flashx.textLayout.conversion.TextConverter;
			import flashx.textLayout.formats.TextLayoutFormat;
			import com.fracturedvisionmedia.utils.TwitterString;
 
			private var myTxt:String = "Everyone should follow @josephlabrecque (http://bit.ly/7NkqrB) - really cool stuff and super-informative insights! #Awesome #Super #LOL";
 
			private function init():void {
				// Configure styling the TextFlow links to match richTxt
				var cfg:Configuration = TextFlow.defaultConfiguration;
				var normalTLF:TextLayoutFormat = new TextLayoutFormat(cfg.defaultLinkNormalFormat);
				normalTLF.color = 0xDCD9D9;
				cfg.defaultLinkNormalFormat = normalTLF;
				TextFlow.defaultConfiguration = cfg;
 
				// Import tweet as HTML
				richTxt.textFlow = TextConverter.importToFlow(TwitterString.instance.parseTweet(myTxt), TextConverter.TEXT_FIELD_HTML_FORMAT);
			}
		]]>
	</fx:Script>
 
	<s:RichEditableText id="richTxt" selectable="false" editable="false" right="10" top="10" bottom="10" color="#DCD9D9" left="10"/>
 
</s:Application>

TwitterString Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.fracturedvisionmedia.utils {
 
	/**
	 * The TwitterString class assists with the parsing of a tweet to add hyperlinks 
	 * around Links, HashTags, and UserNames in a tweet.
	 * @author Joseph Labrecque
	 * v. 0.1.2
	 */ 
 
	public final class TwitterString {
		private static var _instance:TwitterString = new TwitterString();
 
		public function TwitterString(){
			if (_instance != null){
				throw new Error("TwitterString can only be accessed through TwitterString.instance");
			}
		}
 
		public static function get instance():TwitterString {
			return _instance;
		}
 
		public function parseTweet(t:String):String {
			var step1:String = parseHyperlinks(t);
			var step2:String = parseUsernames(step1)
			var step3:String = parseHashtags(step2)
			return step3;
		}
 
		private function parseUsernames(t:String):String {
			var result:String = t.replace(/(^|\s)#(\w+)/g, "$1#<a href='http://search.twitter.com/search?q=$2' target='_blank'>$2</a>");
			return result;
		}
 
		private function parseHashtags(t:String):String {
			var result:String = t.replace(/(^|\s)@(\w+)/g, "$1@<a href='http://www.twitter.com/$2' target='_blank'>$2</a>");
			return result;
		}
 
		private function parseHyperlinks(t:String):String {
			var urlPattern:RegExp = new RegExp("(((f|ht){1}tp://)[-a-zA-Z0-9@:%_\+.~#?&//=]+)", "g")
			var result:String = t.replace(urlPattern, "<a href='$1' target='_blank'>$1</a>");
			return result;
		}
 
	}
}

Download TwitterString

Jan
14

Skinning a Spark Button in Flex 4

By Joseph Labrecque  //  Flex  //  2 Comments

The more I work with Flex 4, the more I understand why certain choices were made regarding the new component architecture, especially in regard to skinning. I stumbled, at first, as the skinning model is quite different and can appear much more cumbersome at first glance. Like most Flex devs, I was used to just modifying the CSS to style Halo components quickly and easily. The Spark model is more complex- but holds a lot more power as demonstrated below.

Example:
How to turn this button…

<s:Button label="Resources"/>

Into This button…

<s:Button label="Resources" skinClass="CustomButton"/>

The only difference being the addition of the CustomButton skin class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" 
      minWidth="21" minHeight="21"
      alpha.disabled="0.5">
 
    <fx:Metadata>
        /** 
         * @copy spark.skins.spark.ApplicationSkin#hostComponent
         */
        [HostComponent("spark.components.Button")]
    </fx:Metadata>
 
    <s:states>
        <s:State name="up" />
        <s:State name="over" />
        <s:State name="down" />
        <s:State name="disabled" />
    </s:states>
 
    <!-- background -->
    <s:Rect left="0" right="0" top="0" bottom="0"
          radiusX="0" radiusY="0" topLeftRadiusX="2" topLeftRadiusY="2" topRightRadiusX="20" topRightRadiusY="80" height="30" width="69">
        <s:stroke>
            <s:SolidColorStroke color="0x001a0a" />
        </s:stroke>
        <s:fill>
			<s:LinearGradient rotation="90">
				<s:GradientEntry color="0x00522d" />
				<s:GradientEntry color="0x003019" />
			</s:LinearGradient>
        </s:fill>
    </s:Rect>
 
    <!-- label -->
    <!--- @copy spark.components.supportClasses.ButtonBase#labelDisplay -->
    <s:Label id="labelDisplay"
             textAlign="center"
             verticalAlign="bottom"
			 paddingLeft="5" paddingRight="10" 
             maxDisplayedLines="1" top="2" left="10" bottom="4" right="10" horizontalCenter="0" verticalCenter="0" color.up="#A0BAA6" color.over="#F0FFF0">
    </s:Label>
</s:Skin>

As you can see, you can pretty much use any sort of visual wizardry you like in here: Solids, Gradients, Bitmaps, Strokes, what-ever!


Super easy to get started too, as you can have Flash Builder duplicate an existing skin to get you started. Just rename and recode. Once within the new skin, you can use the Appearance panel to modify things as you would through Halo (CSS styling) in previous versions of Flex, or get into the nitty-gritty as I’ve done here.

Cool.

Jul
13

CD Baby Has Some Flex Going On…

The music distributor CD Baby just completed a huge update over the weekend. Looks like they have some Flex going on in the user admin area:

cdbaby

It’s just the default Flex styling, so it’s pretty obvious- very cool to see, nonetheless!

Feb
24

Migrating AIR Apps from a Self-Signed Certificate

Security CertificateAfter having deployed many AIR apps with self-signed certificates over the past year or so, when I finally got one from a certificate authority I was quite happy to update my apps with it. Not so fast! You can’t update an AIR app that has been signed with a different certificate than a previously installed signature. It will cause AIR to throw an installation error.

This will be my attempt to document the steps taken to get the certificate migration to function correctly. I’m using Flex Builder 3 on Windows Vista.

In many of my AIR apps, I use the AIR Update Framework which allows an app to check for updates to itself. Anytime a user would try and auto-update or even download and install an updated .air file manually (without first performing an uninstall), they would receive a generic installation error. That’s no good.

My first inclination was to place a warning in the updater XML file letting users know to UNINSTALL the app- then REINSTALL because of the cert change. Not very graceful and the update notes are collapsed by default anyway- no one would see them. That’s when I began searching and found this in the LiveDocs:

-migrate

It tells you a lot but fell a few points short for me. ADT (AIR Development Toolkit) was referenced- was this included in the FB3 SDKs or was this an additional download? Where do I find it?

After a bit of digging around, I located it in “C:\Program Files (x86)\Adobe\Flex Builder 3\sdks\3.2.0\bin”. To get it to work properly though, one should set up an environment variable in Windows. On Vista, this is done by going to System Properties, clicking Advanced System Settings, and pressing the “Environment Variables” button. You’ll want to look for the “Path” variable under “System Variables” and append the location of ADT to this. Be sure to separate each Path value item with a semi-colon.

PATH

The proper syntax for performing a certificate migration is “adt –migrate -storetype pkcs12 -keystore cert.p12 myApp.air myApp.air”. So I opened up a command prompt, navigated to the application directory and punched in my command. No good. ADT spit back an error that it couldn’t locate ‘java’. I know that Java is running on my system- so on a hunch, I added another environment variable to point to my Java installation folder- “C:\Program Files (x86)\Java\jre6\bin”.

Running ADT again and I was prompted for my certificate key and upon entering that, ADT was able to successfully migrate my cert!

Dec
23

Using FlexEvent.IDLE to Determine Inactivity

A FlexEvent.IDLE event will dispatch every 100 milliseconds when there has been no keyboard or mouse activity for 1 second.  So, if you want to have some other method fire off after the user is inactive for 5 minutes (for example), you would set it up as detailed below.

Be sure to import the following classes.  IDLE needs to be bound to a SystemManager instance and we will need to reference the mx_internal namespace later on:

1
2
3
import mx.managers.SystemManager;
import mx.events.FlexEvent;
import mx.core.mx_internal;

You’ll need to tell Flex that you want to use mx_internal as a namespace to access those properties within the SystemManager class. SytemManager has an “idleCounter” property which is super useful to access- but it is scoped to mx_internal and is not normally accessible. Trying to access it without these steps will throw an error:

1
use namespace mx_internal;

SystemManager is automatically instantiated as a part of every Flex app, so we do not need to do this manually. We will, however, need to add an event listener for FlexEvent.IDLE:

1
this.systemManager.addEventListener(FlexEvent.IDLE, userIdle);

Construct the callback method. Five minutes is equal to 300000 milliseconds… divided by 100 ticks and the number we need to check against is 3000. Of course, you’ll probably want something a little shorter in duration for testing:

1
2
3
4
5
private function userIdle(e:FlexEvent):void {
	if(e.currentTarget.mx_internal::idleCounter == 3000){
		//do something!
	}
}

Note that we prefix the idleClounter property with the mx_internal namespace.

That’s it! Now we have a sweet little activity monitor in our app. When activity is detected, idleCounter will automatically reset as well.

About this Website

This is the website of Joseph Labrecque: Senior Multimedia Application Developer for the University of Denver and Owner of Fractured Vision Media, LLC. Joseph is an Adobe Higher Education Leader.

Adobe Higher Education Leader

Adobe Certified

Aggregated by AXNA

Follow me on Twitter!