Home > Adobe Flex, Xuland > FLEX: How to create a wrapping LinkButton

FLEX: How to create a wrapping LinkButton

For my experimental Flex4-powered social networking application Xuland, I wanted to display local news specifically tailored to fit the location that was currently displayed on the map.

A service call to obtain a local newsfeed was easy enough, but I wanted each news title to appear underneath the Xuland map as a link. Using the default Flex LinkButton resulted in something close to what I wanted. Clicking each link opened up the local news story in a separate browser window or tab, however if the title of the news story was longer than the width I had allotted for the LinkButton, the resulting title was cut off:

I needed the LinkButton to essentially wrap without truncating the title. Figuring out how to do so was not easy but after a little digging and a little experimenting, here’s the resulting code.

First, we need to create a non-truncating UITextField that will serve as our textField component within the LinkButton class. The only purpose of this custom UITextField class is to override the truncateToFit Boolean so that it always returns false:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package
{
	import mx.core.UITextField;
 
	public class NonTruncatingUITextField extends UITextField
	{
		public function NonTruncatingUITextField ()
		{
			super();
		}
 
		override public function truncateToFit(s:String = null):Boolean
		{
			return false;
		}
	}
}

Next, we need to utilize that new UITextField class in a customized version of our LinkButton. We’ll extend LinkButton and call it WrappingLinkButton. The primary purpose of this class is to override createChildren and set the textField component property to point to our new NonTruncatingUITextField class.

We’ll also override updateDisplayList to change the y-index of our textField so that it appears higher on the button. At this point, we also need to increase the height of the button to fit our newly wrapped textField. You’ll notice I added a little more logic to underline the text when you mouseOver and to zero out the leading (space between characters):

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
48
49
50
51
52
53
54
55
package
{
	import flash.display.DisplayObject;
	import flash.events.MouseEvent;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
 
	import mx.controls.LinkButton;
	import mx.core.UITextField;
 
	public class WrappingLinkButton extends LinkButton
	{
		private var m_textFormat:TextFormat;
 
		public function WrappingLinkButton()
		{
			super();
			addEventListener(MouseEvent.MOUSE_OVER, onMouseOver);
			addEventListener(MouseEvent.MOUSE_OUT, onMouseOut);
 
			m_textFormat = new TextFormat();
			m_textFormat.leading = 0;
		}
 
		private function onMouseOver( event:MouseEvent ):void
		{
			setStyle( "textDecoration", "underline" );
		}
 
		private function onMouseOut( event:MouseEvent ):void
		{
			setStyle( "textDecoration", "none" );
		}
 
		override protected function createChildren():void
		{
			super.createChildren();
 
			textField = new NonTruncatingUITextField();
			textField.styleName = this;
			textField.multiline = true;
			textField.wordWrap = true;
			textField.autoSize = TextFieldAutoSize.LEFT;
			addChild(DisplayObject(textField));
		}
 
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			textField.y = (this.height - textField.height ) >> 1;
			height = textField.height + getStyle("paddingTop") + getStyle("paddingBottom");
			textField.setTextFormat( m_textFormat );
		}
	}
}

Now we just need to drop the component into our view. I use mine within a custom ItemRenderer component that serves as the item renderer for a DataGroup component that lists my news items vertically:

1
2
3
4
5
6
7
<component:WrappingLinkButton
          width="245"
          label="{ m_news.title }" 
          textAlign="left"
          paddingBottom="0" paddingTop="0"
          paddingLeft="0" paddingRight="0"
          click="onClick()"/>

My click handler simply calls navigateToURL to send our user to the story of their choice. And this is our resulting newsfeed in Xuland:

Hope this helps others out there looking to create their own wrapping LinkButtons (or Buttons). ;)

To read more about Xuland, visit my other blog post regarding this application.

Erich

Categories: Adobe Flex, Xuland Tags:
  1. Ashley Forrester
    December 2nd, 2010 at 02:08 | #1

    Very informative indeed! I have been using Flex-powered social networking applications for classified business needs, and have been very satisfied with the results.

  1. No trackbacks yet.