I've updated my previous blog post on Tree Lines to include a Flex 4/Spark version which uses the MXTreeItemRenderer class.
For more documentation on how to use it see the blog post linked above.
I've also updated the AdvancedDataGrid example to show tree lines in the tree:
Thursday, September 9, 2010
Friday, August 27, 2010
Detecting browser height
Here is an example of one way to find out the height of the browser window from inside Flex. It is very easy to find this out if your have your Flex application set to height="100%". But if you use a fixed height like height="300" then stage.stageHeight and app.height both return 300.
This example uses the ExternalInterface to determine the height of the browser by calling the eval javascript function (it is a built-in function).
E.g.
Different browsers (NS, FF, Chrome, IE, Safari) obviously don't all support this call. So far the window.innerHeight property works on all of them except IE. For IE you can use this one (IE 7 and above I think?):
And if your browser is older you can try this one:
Browsers will also handle errors differently, so if you try to use one of those JavaScript functions in one browser you might get undefined return, and in another browser you might get an error dialog box.
Here is an example of this in action, it opens in a new browser window to show it properly.
If it was embedded on this page using an <iframe> tag then the size returned is that of the iframe, not the browser.
- Browser Height Example -

Obviously if you were interested in the browser width then you could do exactly the same thing but replace innerHeight with innerWidth and clientHeight with clientWidth.
Comments welcome.
This example uses the ExternalInterface to determine the height of the browser by calling the eval javascript function (it is a built-in function).
E.g.
var browserHeight:Number = ExternalInterface.call("eval", "window.innerHeight");
Different browsers (NS, FF, Chrome, IE, Safari) obviously don't all support this call. So far the window.innerHeight property works on all of them except IE. For IE you can use this one (IE 7 and above I think?):
var browserHeight:Number = ExternalInterface.call("eval", "document.documentElement.clientHeight");
And if your browser is older you can try this one:
var browserHeight:Number = ExternalInterface.call("eval", "document.getElementsByTagName('body')[0].clientHeight");
Browsers will also handle errors differently, so if you try to use one of those JavaScript functions in one browser you might get undefined return, and in another browser you might get an error dialog box.
Here is an example of this in action, it opens in a new browser window to show it properly.
If it was embedded on this page using an <iframe> tag then the size returned is that of the iframe, not the browser.
- Browser Height Example -

Obviously if you were interested in the browser width then you could do exactly the same thing but replace innerHeight with innerWidth and clientHeight with clientWidth.
Comments welcome.
Wednesday, August 11, 2010
Synchronized Scrollbars
I recently had a need for two side-by-side TextAreas whose vertical scrollbars were synchronized. So if you drag the left scrollbar, the right one updates, and vice versa.
I've written a utility class called LinkedScrollers that synchronizes the scrolling of two Scrollers. It has 5 public properties:
So another solution is to set the component1 and component2 properties to the two SkinnableComponents that you want to link (Lists, TextAreas, etc). It should work for any SkinnableComponent that contains a "scroller" skin part.
E.g.
Here it is in action, view source enabled (right click on the example below):
As you might guess, this follows on from my previous post on Spark TextArea With Line Numbers.
I've written a utility class called LinkedScrollers that synchronizes the scrolling of two Scrollers. It has 5 public properties:
- enabled (defaults to true) - set to false to allow scrollbars to move independently
- scroller1 - the first Scroller
- scroller2 - the second Scroller
- component1 - the first SkinnableComponent, e.g. List, TextArea
- component2 - the second SkinnableComponent (List, TextArea, etc)
<spark:LinkedScrollers scroller1="{list.scroller}" scroller2="{textArea.scroller}"/>
But unfortunately the scroller property on List/TextArea is not bindable, so that didn't work. You can still use the scroller1 and scroller2 in ActionScript (e.g. in the application's creationComplete handler) to set the scrollers.So another solution is to set the component1 and component2 properties to the two SkinnableComponents that you want to link (Lists, TextAreas, etc). It should work for any SkinnableComponent that contains a "scroller" skin part.
E.g.
<spark:LinkedScrollers component1="{list}" component2="{textArea}"/>
Here it is in action, view source enabled (right click on the example below):
As you might guess, this follows on from my previous post on Spark TextArea With Line Numbers.
Labels:
list,
scrollbar,
scroller,
synchronized,
textarea
Friday, July 16, 2010
Spark TextArea with Line Numbers
Here is a skin that you can use on the Spark TextArea class to show line numbers down the left side of the text.
The line numbers use the same size font as the TextArea.
It is very simply to use, simply set the skinClass property in mxml like this:
If you want a horizontal scroll bar on the TextArea, then set lineBreak="explicit" and the horizontal scrollbar will appear.
Here is an example of it in action (right click to view source).
It would be very easy to modify this skin to make it resizable by adding a resize handle in the bottom right corner. Look at the source code from my previous blog post on Resizable Controls, specifically the flex.utils.spark.resize.ResizableTextAreaSkin class, it uses a custom skin for the Scroller, which adds the resize handle.
The line numbers use the same size font as the TextArea.
It is very simply to use, simply set the skinClass property in mxml like this:
<s:TextArea skinClass="flex.utils.spark.TextAreaLineNumbersSkin"/>
If you want a horizontal scroll bar on the TextArea, then set lineBreak="explicit" and the horizontal scrollbar will appear.
Here is an example of it in action (right click to view source).
It would be very easy to modify this skin to make it resizable by adding a resize handle in the bottom right corner. Look at the source code from my previous blog post on Resizable Controls, specifically the flex.utils.spark.resize.ResizableTextAreaSkin class, it uses a custom skin for the Scroller, which adds the resize handle.
Labels:
line numbers,
spark,
textarea
Monday, June 28, 2010
Flex 4 Spark Resizable Controls
Please go here for Flex 3 Resizable Containers.
I've created a bunch of skins for many of the common Spark components that allows them to be resized. Each of these skins contains a resizeHandle that when dragged allows the control to be resized. There are two resize handle classes that you can use, the default is called flex.utils.spark.resize.ResizeHandleLines. You can replace every occurrence of that class with flex.utils.spark.resize.ResizeHandleDots if you prefer.
Here are a list of resize skins:
With the exception of the ResizableLabel class, all the others are Skins, and as such can be used very simply by setting the skinClass="flex.utils.spark.resize.___Skin" property to the appropriate skin.
Another option is to create a CSS style for ALL spark.components.Scroller classes to use the flex.utils.spark.resize.ResizableScrollerSkin class like this:
** Note that I've renamed the Flex3 package flex.utils.ui.resize.* to the new Flex4/Spark package name flex.utils.spark.resize.*.
The most used skin is the ResizableScrollerSkin, it is used on TextAreas, Lists, DataGrids, Trees, ComboBoxes, DropDownLists, and anything else that uses a Scroller component. The way it works is to use a skin for the Scroller that adds the resize handle and uses custom HScrollBar and VScrollBar classes which leave room for the resize handle (the simplest way I could think to do it). Each of the resizable skins uses the ResizeManager class to handle the mouse events and resize the appropriate control.
The resizable ComboBox and DropDownList skins are slightly different in that they both save the size of the drop down list since it gets destroyed and re-created each time. It also sets the popUpWidthMatchesAnchorWidth="false" after resizing since the width no longer matches the anchor.
I've also added support for restricting the resize in only the vertical or horizontal direction. There are many ways you can do this, you can either set a style on the resize component:
September 30th, 2010 Update:
I've added a new skin called ResizableDraggableTitleWindowSkin that uses the MoveManager class to allow dragging the TitleWindow around the screen. It also adds a small drag handle in the titlebar too.
The same could be done for other classes (e.g. Panel) by following the same procedure. All that is required is a dragComponent (the component that listens for mouse drag events) and a moveComponent (the component that gets moved - in this case it is the TitleWindow).
Here is an example of most of the skins, view-source enabled.
I've created a bunch of skins for many of the common Spark components that allows them to be resized. Each of these skins contains a resizeHandle that when dragged allows the control to be resized. There are two resize handle classes that you can use, the default is called flex.utils.spark.resize.ResizeHandleLines. You can replace every occurrence of that class with flex.utils.spark.resize.ResizeHandleDots if you prefer.
Here are a list of resize skins:
- ResizableTextAreaSkin (skin for spark.components.TextArea)
- ResizableDropDownListSkin (skin for spark.components.DropDownList)
- ResizableComboBoxSkin (skin for spark.components.ComboBox)
- ResizablePanelSkin (skin for spark.components.Panel)
- ResizableTitleWindowSkin (skin for spark.components.TitleWindow)
- ResizableDraggableTitleWindowSkin (draggable skin for spark.components.TitleWindow)
- ResizableScrollerSkin (skin for spark.components.Scroller)
- ResizableTitledBorderBoxSkin (skin for flex.utils.spark.TitledBorderBox)
- ResizableLabel (extends spark.components.Label, not a skin)
With the exception of the ResizableLabel class, all the others are Skins, and as such can be used very simply by setting the skinClass="flex.utils.spark.resize.___Skin" property to the appropriate skin.
Another option is to create a CSS style for ALL spark.components.Scroller classes to use the flex.utils.spark.resize.ResizableScrollerSkin class like this:
<fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace spark "flex.utils.spark.*";
@namespace resize "flex.utils.spark.resize.*";
/* Make all Scroller's use the resizable scroller skin. */
s|Scroller {
skin-class: ClassReference("flex.utils.spark.resize.ResizableScrollerSkin");
}
</fx:Style>
@namespace s "library://ns.adobe.com/flex/spark";
@namespace mx "library://ns.adobe.com/flex/mx";
@namespace spark "flex.utils.spark.*";
@namespace resize "flex.utils.spark.resize.*";
/* Make all Scroller's use the resizable scroller skin. */
s|Scroller {
skin-class: ClassReference("flex.utils.spark.resize.ResizableScrollerSkin");
}
</fx:Style>
** Note that I've renamed the Flex3 package flex.utils.ui.resize.* to the new Flex4/Spark package name flex.utils.spark.resize.*.
The most used skin is the ResizableScrollerSkin, it is used on TextAreas, Lists, DataGrids, Trees, ComboBoxes, DropDownLists, and anything else that uses a Scroller component. The way it works is to use a skin for the Scroller that adds the resize handle and uses custom HScrollBar and VScrollBar classes which leave room for the resize handle (the simplest way I could think to do it). Each of the resizable skins uses the ResizeManager class to handle the mouse events and resize the appropriate control.
The resizable ComboBox and DropDownList skins are slightly different in that they both save the size of the drop down list since it gets destroyed and re-created each time. It also sets the popUpWidthMatchesAnchorWidth="false" after resizing since the width no longer matches the anchor.
I've also added support for restricting the resize in only the vertical or horizontal direction. There are many ways you can do this, you can either set a style on the resize component:
.resizePanel {
resize-direction: vertical; /* or horizontal */
}
Or you can call a static method on the ResizeManager class:resize-direction: vertical; /* or horizontal */
}
ResizeManager.setResizeDirection(resizePanel, "vertical"); // or "horizontal"
Or if you can access the ResizeManager class (usually stored in the skin class), then you can set the resizeDirection property on the manager like this:resizeManager.resizeDirection = "vertical"; // or "horizontal";
There are constants defined in the ResizeManager class for "vertical", "horizontal", and "both" (default). September 30th, 2010 Update:
I've added a new skin called ResizableDraggableTitleWindowSkin that uses the MoveManager class to allow dragging the TitleWindow around the screen. It also adds a small drag handle in the titlebar too.
The same could be done for other classes (e.g. Panel) by following the same procedure. All that is required is a dragComponent (the component that listens for mouse drag events) and a moveComponent (the component that gets moved - in this case it is the TitleWindow).
Here is an example of most of the skins, view-source enabled.
Labels:
resizable controls,
scroller,
spark
Subscribe to:
Posts (Atom)
