Mirroring and bidirectional text

Introduction to mirroring and bidirectional text

here are two primary ways to control the appearance of an application that supports both left-to-right (LTR) and right-to-left (RTL) languages:
  • Layout mirroring — Layout mirroring is the process of flipping the appearance of the layout controls. For example, in an RTL application, vertical scroll bars should appear on the left instead of the right. For horizontal scrollbars, the thumb should appear on the right side of the control instead of the left. Layout mirroring is commonly used to make a UI match the direction of an RTL language.

  • Text direction — Text direction defines the direction that text flows in the text controls. For RTL languages such as Hebrew and Arabic, the characters should render from the right side to the left. This also includes bidirectional text support, where a control might need to render some of the text RTL, and some of the text LTR in the same control. The Spark Flex text controls handle directionality of the text internally. They do not use mirroring to render text.

To change an application's layout from LTR to RTL, set the layoutDirection property of the application object to "rtl". The direction of text is automatically set based on the characters used, but you should also set the direction style property to "rtl" if the majority of your text is RTL. This property instructs the text control to apply RTL rules to the text.
The following example lets you change the layoutDirection and direction style properties on the application from "ltr" to "rtl":
<?xml version="1.0" encoding="utf-8"?> 
<!-- mirroring/DynamicMirroring.mxml --> 
<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" 
               height="400" width="400">    
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
    
    <fx:Script> 
        <![CDATA[        
            import mx.core.LayoutDirection; 
            
            private function setDirectionProps():void { 
                panel1.setStyle('direction', ddl1.selectedItem); 
                panel1.setStyle('layoutDirection', ddl1.selectedItem);              
            } 
        ]]> 
    </fx:Script> 
    
    <s:Panel id="panel1" title="Panel With Non-Mirrored Content" width="350" 
             layoutDirection="{LayoutDirection.LTR}"> 
        <s:layout> 
            <s:VerticalLayout/> 
        </s:layout> 
        <s:Label text="This panel contains content that is not mirrored."/> 
        <s:Button label="This Button is not mirrored in the container"/> 
        <s:DropDownList id="ddl1" requireSelection="true" selectedIndex="0" change="setDirectionProps()"> 
            <s:ArrayList source="['ltr','rtl']"/> 
        </s:DropDownList>       
    </s:Panel> 
</s:Application>

Mirroring is not supported when you set the compatibility-version compiler option to 3.0.0 or when the theme is Halo or Mobile. Mirroring is only supported by the Wireframe and Spark themes.

Layout mirroring

Layout mirroring refers to how containers and controls are drawn on the screen. The default direction is LTR. You can change any container or control that implements the ILayoutDirectionElement interface to lay out from right to left by setting the layoutDirection property to "rtl". This interface includes all controls that implement the IVisualElement interface as well as some assets that do not implement this interface.

The recommended method of using layoutDirection is to set it on the Application container so that all child containers and controls in the application inherit its value. You can set the layoutDirection property in one of the following ways:
  • In MXML. For example:
    <s:Panel id="myPanel" layoutDirection="rtl">
  • With the setStyle() method. For example:
    myPanel.setStyle("layoutDirection","rtl");
The following example shows two Panel containers. One sets the layoutDirection property to "rtl" and the other to "ltr":
<?xml version="1.0" encoding="utf-8"?> 
<!-- mirroring/SimpleLayoutMirroring.mxml --> 
<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" 
               height="400" width="400"> 
    
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
    
    <fx:Script> 
        <![CDATA[        
            import mx.core.LayoutDirection;        
        ]]> 
    </fx:Script> 
    
    <s:Panel title="Panel With Non-Mirrored Content" width="350" 
             layoutDirection="{LayoutDirection.LTR}"> 
        <s:layout> 
            <s:VerticalLayout/> 
        </s:layout> 
        <s:Label text="This panel contains content that is not mirrored."/> 
        <s:Button label="This Button is not mirrored in the container"/> 
        <s:DropDownList requireSelection="true" selectedIndex="0"> 
            <s:ArrayList source="['Drop','Down','List']" /> 
        </s:DropDownList>       
    </s:Panel> 
    
    <s:Panel title="Panel With Mirrored Content" width="350" 
             layoutDirection="{LayoutDirection.RTL}"> 
        <s:layout> 
            <s:VerticalLayout/> 
        </s:layout> 
        <s:Label text="This panel contains content that is mirrored."/> 
        <s:Button label="This Button is mirrored inside the container"/> 
        <s:DropDownList requireSelection="true" selectedIndex="0"> 
            <s:ArrayList source="['Drop','Down','List']" /> 
        </s:DropDownList>       
    </s:Panel> 
</s:Application>
Instead of using the strings "ltr" or "rtl", the layoutDirection style property can also take the following constants:
  • mx.core.LayoutDirection.LTR

  • mx.core.LayoutDirection.RTL

Text direction

Text direction refers to the direction that characters are rendered in text-based controls. Some languages, such as Hebrew and Arabic, are read from right to left. Most text-based controls auto-detect the direction of the text based on the character codes of the text content, but specifying the direction ensures that the punctuation follows the appropriate (RTL or LTR) rules.

As with the layoutDirection property, you typically set the direction property on the application or the parent container of the text-based control.

You can set the direction property in one of the following ways:
  • In MXML. For example:
    <s:Panel id="myPanel" direction="rtl">
  • With the setStyle() method. For example:
    myPanel.setStyle("direction","rtl");
The following example shows two Panel containers. One sets the direction property to RTL and the other to LTR:
<?xml version="1.0" encoding="utf-8"?> 
<!-- mirroring/SimpleTextMirroring.mxml --> 
<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" 
               height="400" width="400"> 
    
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
    
    <fx:Script> 
        <![CDATA[        
            import mx.core.LayoutDirection;        
        ]]> 
    </fx:Script> 
    
    <s:Panel title="Panel With Non-Mirrored Content" width="350" 
             direction="ltr"> 
        <s:layout> 
            <s:VerticalLayout/> 
        </s:layout> 
        <s:Label text="This panel contains content that is not mirrored."/> 
        <s:Button label="This Button is not mirrored in the container."/> 
        <s:DropDownList requireSelection="true" selectedIndex="0"> 
            <s:ArrayList source="['Drop','Down','List']" /> 
        </s:DropDownList>       
    </s:Panel> 
    
    <s:Panel title="Panel With Mirrored Content" width="350" 
             direction="rtl"> 
        <s:layout> 
            <s:VerticalLayout/> 
        </s:layout> 
        <s:Label text="This panel contains content that is mirrored."/> 
        <s:Button label="This Button is mirrored inside the container."/> 
        <s:DropDownList requireSelection="true" selectedIndex="0"> 
            <s:ArrayList source="['Drop','Down','List']" /> 
        </s:DropDownList>       
    </s:Panel> 
 
</s:Application>

The direction style property only affects punctuation in this example. The characters themselves are not rendered from right to left because they use an LTR-based character set.

Support for setting the direction on text controls is built into text controls in the Spark component set because those text controls are based on FTE (Flash Text Engine). Text-based controls that are based on the TextField control do not support mirroring or bidirectional text. To use FTE with MX text-based controls, you must adjust your compiler settings. For more information, see Mirroring with text controls.

Bidirectional text refers to text that contains both RTL and LTR content. For example, if you write a sentence in an RTL language such as Hebrew, but include the name of a company, such as Apache. The compiler recognizes characters codes that use RTL and LTR and renders the text appropriately.

The following example shows bidirectional text:
<?xml version="1.0"?> 
<!-- mirroring/BiDiText.mxml --> 
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009"    
    xmlns:mx="library://ns.adobe.com/flex/mx"     
    xmlns:s="library://ns.adobe.com/flex/spark" 
    creationComplete="addText()"> 
    
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout>    
    <fx:Script> 
        <![CDATA[        
            import flashx.textLayout.formats.*; 
            import spark.utils.TextFlowUtil; 
            private function addText():void { 
                myRT.textFlow = TextFlowUtil.importFromString("school is written " + 
                    String.fromCharCode(0x0645, 0x062f, 0x0631, 0x0633, 0x0629) + 
                    " in Arabic and " + String.fromCharCode(0x05E1, 0x05B5, 0x05E4, 0x05B6, 0x05E8) + 
                    " in Hebrew."); 
            } 
        ]]> 
    </fx:Script> 
    
    <s:Panel title="Example of Bidirectional text"> 
        <s:RichText id="myRT" width="400" height="150"/> 
    </s:Panel>    
</s:Application>

In this example, the direction property is set to "rtl". This causes the punctuation to be reversed so that the period is on the left.

In some cases, you cannot set the direction style in MXML because some components (such as the ProgressBar and TileList controls) already define a direction property that defines other behavior. For more information, see Overlapping direction properties.

Inheritance

The values of the layoutDirection and direction style properties are inherited by most components from their parent. As a result, you typically set these properties on the Application tag so that the properties are used consistently across the entire application. While it is possible to set these styles on individual components, this can be a cumbersome and mistake-prone approach.

In addition, if you set the style properties on individual components, you override the defaults set in the global.css file. These defaults define expected behavior. For example, you typically do not want to reverse the direction of an Image or VideoDisplay control when you mirror the contents of an application.

Some components, such as text-based controls, and the Image, BitmapImage, VideoPlayer, and VideoDisplay controls do not inherit the value of the layoutDirection style property. These components override the values of this property in the defaults.css file. They either do not support the property, support it in a different manner, or do not inherit the value because inheriting it would create unexpected results.

The following table describes the components that do not inherit the value of the layoutDirection style property:

Control

Description

BitmapImage, Image

The Image (both Spark and MX) and BitmapImage components do not inherit the value of the layoutDirection property from the container because Flex assumes that you do not want to mirror the contents.

To override this behavior and reverse the contents of the MX Image and Spark BitmapImage controls, set the value of the layoutDirection property directly on the control. You cannot reverse the contents of the Spark Image control with the layoutDirection property. For more information, see Images and video controls.

VideoDisplay, VideoPlayer

The VideoDisplay and VideoPlayer components do not inherit the value of the layoutDirection property for the same reason that the Image components do not: the assumption is that the contents should not be mirrored.

However, you can override the default behavior by setting the layoutDirection property directly on the control. In this case, the VideoDisplay control mirrors the actual video being displayed.

The VideoPlayer mirrors the subcontrols that are used to control the video but not the video itself.

Spark text-based controls, such as those based on the TextBase class (Label and RichText) and those including the RichEditableText control (RichEditableText, TextArea, and TextInput)

The reason that the Spark text-based controls do not inherit the value of the layoutDirection property is that they use FTE/TLF to auto-detect the direction of the text. The text characters are not mirrored in the same way that UI controls are mirrored.

The input cursor for the TextArea and TextInput controls does not rely on the layoutDirection property, but rather on the value of the direction property to determine the starting position of the cursor when the control gains focus.

In addition to being a style, the layoutDirection property is defined on the ILayoutDirectionElement interface. All UIComponents inherit the properties of this interface. As a result, you can also set the layoutDirection as a property on an object. If a component's layoutDirection property is set to null, the component inherits the value from its parent. For components that implement the ILayoutDirectionElement interface, this means that setting layoutDirection=null is equivalent to setStyle("layoutDirection", undefined).

Components

This section describes the behavior of the components when you set layoutDirection to "rtl" on the Application container. In most cases, the behavior of Spark and MX controls is the same.

Basic UI controls

Control

Description

Alert

The Alert title is on the right. The text is not mirrored. Any icons are on the right. All buttons are arranged the opposite of their LTR order. For example, if buttons were "OK" and "Cancel", they appear as "Cancel" and "OK".

Button

The appearance of the Button is mirrored but the label text is not. If you use the Button control with an embedded icon, this icon is aligned on the right but the image itself is not reversed.

CheckBox

The label is rendered on the left. The check icon is not mirrored.

ColorPicker

The layout of the selector box and text input are reversed. The color grid is reversed, with the most common colors appearing on the right.

DateChooser

The direction of days and months are mirrored. The text for the days and numbers is not mirrored. The forward month arrow is on the left and back month arrow button is on the right.

DateField

The calendar icon appears on the left with the text input on the right. The calendar that opens looks like a mirrored DateChooser control. When you place a DateField control, be sure to leave enough room on the left side for the popup.

When there is sufficient room on the left the DateChooser popup is aligned correctly. If there is not enough area on the left, the calendar that pops up can be cut off by the screen edge.

DownloadProgressBar

The DownloadProgressBar is not mirrored. It always fills from left to right.

Image

The contents of the Image control are not mirrored. To mirror the contents of an MX Image control, set the value of the layoutDirection property directly on the component. You cannot mirror the contents of the Spark Image control. Use the Spark BitmapImage or MX Image control instead.

Link

Button order is from right to left. All icons are aligned on the right of each button.

NumericStepper

The text in the input is aligned to the right. The navigation buttons are on the left. Numbers appear the same.

PopUpButton

The text is aligned to the right. The drop down icon is on the left.

PopUpMenuButton

See PopUpButton and Menu.

ProgressBar

The ProgressBar control fills in the track from right to left. The label is aligned to the right. The ProgressBar also has a direction style property that you can use to set the direction of the filling.

RadioButton

Labels are on the left of the radio icon.

RadioButtonGroup

See RadioButton control.

ScrollBar, HScrollBar, VScrollBar

Vertical scrollbars are the same, regardless of the value of the layoutDirection property. For horizontal scrollbars, the thumb defaults to the right, which is scroll position 0.

Slider, HSlider, VSlider

For the HSlider control, the slider thumb's starting point is reversed. The minimum value is at the right-most point on the slider, and the maximum value is at the left-most point.

Spinner

This component does not change when mirrored.

SWFLoader

The SWFLoader control mirrors its contents. In some cases, this might be undesireable. The workaround is to explicitly set the value of the layoutDirection property on the SWFLoader control when you do not want it to mirror the contents.

VideoDisplay

The contents of the VideoDisplay control are not mirrored, unless you explicitly set layoutDirection directly on the control.

VideoPlayer

The contents of the VideoPlayer control are never mirrored. The player controls are mirrored so that the slider thumb starts on the right and the location of the play button is on the right.

List-based controls

Control

Description

ButtonBar

Button order is from right to left. All icons are aligned on the right of each button.

ComboBox

In the editable field, text is aligned to the right.

DropDownList

The icon appears on the left side. List items are right aligned.

FileSystemComboBox

Same as the MX ComboBox control.

FileSystemList

Same as the MX List control.

List, HorizontalList

All items in the List are aligned to the right. ScrollBars are on the left (if they are necessary). For a horizontal list, item 0 begins on the right. Items are laid out right to left. A horizontal scroll bar thumb is positioned at scrollPosition 0 on the right.

Note that for HorizontalList, the direction property requires a value of TileBaseDirection.HORIZONTAL or TileBaseDirection.VERTICAL. The direction style supports "ltr" and "rtl".

The direction property on the MX List and Spark List controls cannot be set in ActionScript.

Containers

Control

Description

Accordion

The labels and icons are aligned to the right in the Accordion headers. All of the child controls of the Accordion panes inherit the layoutDirection="rtl" setting, unless the child controls override this value, either in the application or in the defaults.css file.

DividedBox

The first content area of a DividedBox is on the right.

Form

Form item labels are on the right on controls. The form heading is aligned right.

Grid

Grid items move from right to left and top to bottom.

HTML (AIR only)

The contents of the HTML control are not mirrored.

Panel

The title and any icons are aligned right. All of the child controls of the Panel container inherit the layoutDirection="rtl" setting, unless the child controls override this value, either in the application or in the defaults.css file.

TabNavigator

Tabs are laid out from right to left.

TileList

The first item is at the top right of the TileList. Items are laid out from right to left. The direction property requires a value of TileBaseDirection.HORIZONTAL or TileBaseDirection.VERTICAL. The direction style supports "ltr" and "rtl". The direction property on the TileList control cannot be set in ActionScript.

TitleWindow

The title is aligned on the right. The close button is aligned on the left.

Window

The title is aligned at the top right. All children are right aligned.

WindowedApplication (AIR only)

The WindowedApplication title is aligned at the top right. Controls of the WindowedApplication are at the top left. Status text is aligned on the right.

Data-driven controls

Control

Description

MX chart controls

For CartesianChart-based charting controls, the point of origin is the lower right. To align the DataTips to the right, use the direction style property. For more information, see Charting controls.

DataGrid

Headers and all text are aligned right. Sort arrows are aligned left. Focus in editors moves from right to left. Column 0 is on the far right.

FileSystemDataGrid

Same as the MX DataGrid control.

FileSystemTree

Same as the MX Tree control.

Menu

Items are aligned right and submenus open to the left.

MenuBar

MenuBar data provider items are laid out from right to left. Submenus open to the left.

Tree

Items are aligned on the right. Items open to the left. The icons are reversed.

Text-based controls

The Spark text-based controls support bidirectionality. They auto-detect the direction of text based on the character codes. MX text-based controls do not support mirroring or bidirectionality. When using Spark text-based controls, you should set the direction property on the parent container or application. Setting the direction property causes the control to render punctuation properly as well as place the cursor in the correct location when the control gains focus.

For most text controls, changing the layout direction has no effect. This is mostly because most text controls do not have chrome that would require laying out differently. The following table describes the effects of changing layoutDirection on text controls:

Control

Description

Label

No change when layoutDirection="rtl".

RichEditableText

No change when layoutDirection="rtl".

RichText

No change when layoutDirection="rtl".

RichTextEditor

No change when layoutDirection="rtl". Note that the RichTextEditor control does not support mirroring or bidirectional text.

Text

No change when layoutDirection="rtl". Note that the Text control does not support mirroring or bidirectional text.

TextArea

Spark TextArea: Text is aligned right. ScrollBars are on the left. Cursor starts on the right of the TextInput control, but only if direction="rtl".

MX TextArea: Does not support mirroring or bidirectional text. Use the Spark TextArea control instead.

TextInput

Spark TextInput: Text is aligned right. Cursor starts on the right of the TextInput control, but only if direction="rtl".

MX TextInput: Does not support mirroring or bidirectional text. Use the Spark TextInput control instead.

For more information, see Mirroring with text controls.

Mirroring with text controls

Text in applications that use layout mirroring should generally read from right to left. Chrome on the text controls should lay out with an emphasis on right to left navigation.

The Flex compiler auto-detects the direction that text should read based on the Unicode values of the characters. When the characters use an RTL language such as Arabic or Hebrew, TLF-based text controls reverse the order in which they are written.

Flex adjusts the location of punctuation marks such as periods, exclamation points, and parentheses when the direction is set to "rtl". In addition, Flex also adjusts number separators, paragraph breaks, and soft hyphens, as well as other non-character entities so that their position makes sense. The algorithms for this are described in Description of the Unicode bidirectional algorithm.

The direction of the text itself is only reversed if the character set contains codes that instruct the compiler to read from RTL.

All text-based controls in the Spark component set support the direction property because they support FTE/TLF. Many text-based controls in the MX component set support the direction property.

If your application uses text-based controls in the MX component set such as MX Label, you must configure the compiler to use FTE, which supports bidirectional text. Otherwise, the text will render from LTR regardless of the character set you use. To ensure that MX controls use FTE, you can apply the MXFTEText.css theme file:
mxmlc -theme+=themes/MXFTEText.css MyApp.mxml

Selecting this option causes most internal dependencies on UITextField to be replaced with UIFTETextField, which supports FTE. The MX TextInput, TextArea, and RichText text classes do not include this support. You should replace these controls with the equivalent Spark text-based controls.

For text controls that have columns, the direction style property also affects the column order. When direction is set to "rtl", the first column is on the right.

The MX RichTextEditor control does not support mirroring or bidirectional text.

Mirroring with skins

If you create custom skins, you should be aware of the effects on the skins when they are mirrored. In general you do not have to change your skins to use mirroring. In some cases, however, skins use absolute positioning to draw elements of the skin. You might need to edit the skin classes to make them appear correctly when setting layoutDirection to "rtl".

Mirroring is supported for components that use the Spark and Wireframe themes. It is not supported for components that use the Halo theme, or when you set the compatibility-version compiler option to 3.0.0.

Mirroring with effects

Effects that specify a direction, such as Wipe, or that incorporate a direction, such as WipeRight and WipeLeft, are not reversed when layoutDirection is set to "rtl". The effect always wipes in the direction that is defined by the effect, regardless of the value of the layoutDirection property.

The following example shows that when you change the layoutDirection, the direction of the Wipe does not change:
<?xml version="1.0"?> 
<!-- mirroring\EffectMirroring.mxml --> 
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:mx="library://ns.adobe.com/flex/mx" 
               xmlns:s="library://ns.adobe.com/flex/spark"> 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
    
    <s:states> 
        <s:State name="default"/> 
        <s:State name="vis"/> 
    </s:states> 
    
    <s:transitions> 
        <s:Transition fromState="*" toState="*"> 
            <s:Sequence target="{myB}"> 
                <s:Wipe id="wipeEffect"  
                        direction="right" 
                        duration="1000"/> 
            </s:Sequence> 
        </s:Transition> 
    </s:transitions> 
 
    <fx:Script> 
        <![CDATA[ 
            private function setDirectionProps():void { 
                this.setStyle('layoutDirection', ddl1.selectedItem);                
            }           
        ]]> 
    </fx:Script> 
    
    <s:Panel title="Wipe Effect"> 
        <s:layout> 
            <s:VerticalLayout paddingTop="15" paddingLeft="15"/> 
        </s:layout> 
        <s:Button id="myB" label="Wipe Effect" 
          visible.default="false" visible.vis="true"/>        
        <s:Button label="Show Button" 
                  click="currentState='vis'"/> 
        <s:Button label="Hide Button" 
                  click="currentState='default'"/> 
    </s:Panel> 
 
    <s:DropDownList id="ddl1" requireSelection="true" selectedIndex="0" change="setDirectionProps()"> 
        <s:ArrayList source="['ltr','rtl']"/> 
    </s:DropDownList>       
</s:Application>

Effects that specify x and y coordinates, such as Zoom and Move, apply the transform operations relative to the object. Because mirroring changes the location of the x coordinate, these effects are effectively reversed when the value of the layoutDirection property is changed.

The following example shows that when the layoutDirection changes, the zoom effect changes its destination point:
<?xml version="1.0"?> 
<!-- mirroring\MoveEffectMirroring.mxml --> 
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark"> 
 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
    
    <fx:Declarations> 
        <s:Move id="moveOut" target="{targetImg}" xBy="100"/> 
        <s:Move id="moveBack" target="{targetImg}" xBy="-100"/> 
    </fx:Declarations> 
 
    <fx:Script> 
        <![CDATA[ 
            private function setDirectionProps():void { 
                this.setStyle('layoutDirection', ddl1.selectedItem);                
            }           
        ]]> 
    </fx:Script> 
 
    <s:Panel title="Move Effect Example" height="200" width="300"> 
        <s:Image id="targetImg" source="@Embed(source='../assets/logosmall.jpg')"/> 
        <s:Button id="b1" 
                  left="5" bottom="5" 
                  label="Move Out" click="moveOut.play();"/> 
        <s:Button id="b2" 
                  left="120" bottom="5" 
                  label="Move Back" click="moveBack.play();"/> 
    </s:Panel> 
 
    <s:DropDownList id="ddl1" requireSelection="true" selectedIndex="0" change="setDirectionProps()"> 
        <s:ArrayList source="['ltr','rtl']"/> 
    </s:DropDownList>       
</s:Application>

When using coordinate-based effects with controls that do not inherit the layoutDirection style property, you might need to customize the target of the effect.

For example, if you apply the Scale effect to an Image control while the application is RTL, the Image's coordinates will not be mirrored. The result is that the Scale effect's point of origin is the upper left even when the application is RTL. To have the effect play correctly, you might need to explicitly set the Image control's layoutDirection to "rtl", but then the image itself is reversed as well.

The following example shows how the effect plays incorrectly when the layout for the application is RTL, but the layout for the image is not RTL:
<?xml version="1.0"?> 
<!-- mirroring\ScaleEffectMirroring.mxml --> 
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark"> 
 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
 
    <fx:Declarations> 
        <s:Scale id="scaleUp" target="{targetImg}" scaleXBy="2" scaleYBy="2"/> 
        <s:Scale id="scaleDown" target="{targetImg}" scaleXBy="-2" scaleYBy="-2"/> 
    </fx:Declarations> 
 
    <fx:Script> 
        <![CDATA[ 
            private function setAppDirection():void { 
                this.setStyle('layoutDirection', ddl1.selectedItem);                
            }           
            private function setImageDirection():void { 
                /* Note that this example uses an MX Image control rather than a Spark Image control. 
                    Spark images cannot be reversed with the layoutDirection property. */ 
                targetImg.setStyle('layoutDirection', ddl2.selectedItem);               
            }           
        ]]> 
    </fx:Script> 
 
    <s:Panel title="Scale Effect Example" height="300" width="300"> 
        <s:layout> 
            <s:VerticalLayout paddingTop="15" paddingLeft="15"/> 
        </s:layout> 
        
        <mx:Image id="targetImg" source="@Embed(source='../assets/logosmall.jpg')"/>        
        <s:Button id="b1" label="Increase" click="scaleUp.transformX=-100;scaleUp.play();"/> 
        <s:Button id="b2" label="Decrease" click="scaleDown.play();"/> 
    </s:Panel> 
 
    <s:HGroup>      
        <s:Label text="Set Application's layoutDirection:"/> 
        <s:DropDownList id="ddl1" requireSelection="true" selectedIndex="0" change="setAppDirection()"> 
            <s:ArrayList source="['ltr','rtl']"/> 
        </s:DropDownList>       
    </s:HGroup> 
 
    <s:HGroup> 
        <s:Label text="Set Image's layoutDirection:"/> 
        <s:DropDownList id="ddl2" requireSelection="true" selectedIndex="0" change="setImageDirection()"> 
            <s:ArrayList source="['ltr','rtl']"/> 
        </s:DropDownList>       
    </s:HGroup> 
 
</s:Application>

To workaround this issue, you should use two separate images, one for when the application's layout is RTL and one for when the application's layout is LTR. Then load the appropriate image when the layout changes.

Mirroring graphics and video

Images and video controls

Image and video controls do not inherit layout direction. The BitmapImage, Spark and MX Image, VideoPlayer, and VideoDisplay controls do not mirror their contents when you set the layoutDirection property on the application or parent container. These controls override the value of this property in the globals.css file because the expected behavior of images or videos is that the contents are not mirrored.

You can override this behavior in most cases, so that the contents of these controls is mirrored. You do this by setting the value of the layoutDirection property to "rtl" directly on the control. This is true for all the controls mentioned except Spark Image. The Spark Image control does not mirror its contents regardless of the value of the layoutDirection property because it is actually a child of the BitmapImage control (and image-related controls do not inherit the layout direction). To mirror the image, use the Spark BitmapImage or MX Image control.

As with images, icons are typically not mirrored, even if the component that uses the icon is reversed (except in some special cases, such as the disclosure icon in a Tree control).

To mirror the contents of the MX Image, BitmapImage, or VideoDisplay controls, set the layoutDirection property directly on the control. You cannot mirror the contents of the VideoPlayer control or the Spark Image control.

The following example sets the layoutDirection on the Application tag to "rtl", and then sets the layoutDirection property to "rtl" directly on several of the images. This example shows that the first image is not mirrored because it does not override the layoutDirection property and does not inherit its value from the Application container. The second image is also not mirrored because the Spark Image control does not reverse when the property is set on it. The third and fourth images are mirrored because the MX Image and Spark BitmapImage controls support setting layoutDirection directly on them.
<?xml version="1.0" encoding="utf-8"?> 
<!-- mirroring\MirroredImage.mxml --> 
<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" 
       width="750" 
       layoutDirection="rtl"> 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
 
    <s:Label text="application.layoutDirection = rtl"/> 
    
    <s:HGroup>      
        <s:Panel title="Spark Image with default layoutDirection" height="150" width="250"> 
            <s:layout> 
                <s:VerticalLayout paddingTop="15" paddingLeft="15"/> 
            </s:layout> 
            <s:Image source="@Embed(source='../assets/logosmall.jpg')"/>           
        </s:Panel> 
    
        <s:Panel title="Spark Image with layoutDirection=rtl" height="150" width="250"> 
            <s:layout> 
                <s:VerticalLayout paddingTop="15" paddingLeft="15"/> 
            </s:layout> 
            <s:Image source="@Embed(source='../assets/logosmall.jpg')" layoutDirection="rtl"/>         
        </s:Panel> 
    </s:HGroup> 
 
    <s:HGroup>      
        <s:Panel title="MX Image with layoutDirection=rtl" height="150" width="250"> 
            <s:layout> 
                <s:VerticalLayout paddingTop="15" paddingLeft="15"/> 
            </s:layout> 
            <mx:Image source="@Embed(source='../assets/logosmall.jpg')" layoutDirection="rtl"/>           
        </s:Panel> 
    
        <s:Panel title="BitmapImage with layoutDirection=rtl" height="150" width="250"> 
            <s:layout> 
                <s:VerticalLayout paddingTop="15" paddingLeft="15"/> 
            </s:layout> 
            <s:BitmapImage source="@Embed(source='../assets/logosmall.jpg')" layoutDirection="rtl"/>         
        </s:Panel> 
    </s:HGroup> 
</s:Application>
You can also cause the contents of image controls to be mirrored by setting the scaleX property to -1 rather than setting the layoutDirection property; for example:
sparkImage.scaleX = -1;

FXG and MXML graphics

FXG graphics and MXML graphics are mirrorred by default. When the application or parent container sets the layoutDirection property, the FXG component and the MXML graphic are mirrorred.

The following example shows a simple FXG component, and an MXML graphic, that inherit the application's layoutDirection, and are therefore mirrored:
<?xml version="1.0" encoding="utf-8"?> 
<!-- mirroring\MirroredFXG.mxml --> 
<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" 
       xmlns:custom="*" 
       layoutDirection="rtl" 
       width="600" height="300"> 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
 
    <s:Label text="application.layoutDirection = rtl"/> 
 
    <s:HGroup> 
        <s:Panel title="FXG: layoutDirection = default" height="150" width="250"> 
            <s:layout> 
                <s:VerticalLayout paddingTop="15" paddingLeft="15"/> 
            </s:layout> 
            <custom:ArrowAbsolute/>         
        </s:Panel>    
        <s:Panel title="MXML: graphic layoutDirection = default" height="150" width="250"> 
            <s:layout> 
                <s:VerticalLayout paddingTop="15" paddingLeft="15"/> 
            </s:layout> 
            <!-- Use absolute coordinates. --> 
            <s:Graphic>    
                <!-- Use Use compact syntax with absolute coordinates. --> 
                <s:Path data=" 
                        M 20 0 
                        C 50 0 50 35 20 35 
                        L 15 35 
                        L 15 45 
                        L 0 32 
                        L 15 19 
                        L 15 29 
                        L 20 29 
                        C 44 29 44 6 20 6"> 
                    <!-- Define the border color of the arrow. --> 
                    <s:stroke> 
                        <s:SolidColorStroke color="0x888888"/> 
                    </s:stroke> 
                    <!-- Define the fill for the arrow. --> 
                    <s:fill> 
                        <s:LinearGradient rotation="90"> 
                            <s:GradientEntry color="0x000000" alpha="0.8"/> 
                            <s:GradientEntry color="0xFFFFFF" alpha="0.8"/> 
                        </s:LinearGradient> 
                    </s:fill> 
                </s:Path> 
            </s:Graphic> 
        </s:Panel>      
    </s:HGroup> 
</s:Application>
This example uses the following FXG file as a custom component:
<?xml version="1.0" encoding="utf-8"?> 
<!-- fxg/comps/ArrowAbsolute.fxg --> 
<Graphic xmlns="http://ns.adobe.com/fxg/2008" version="2">    
    <!-- Use Use compact syntax with absolute coordinates. --> 
    <Path data=" 
         M 20 0 
         C 50 0 50 35 20 35 
         L 15 35 
         L 15 45 
         L 0 32 
         L 15 19 
         L 15 29 
         L 20 29 
         C 44 29 44 6 20 6"> 
         <!-- Define the border color of the arrow. --> 
         <stroke> 
              <SolidColorStroke color="#888888"/> 
         </stroke> 
         <!-- Define the fill for the arrow. --> 
         <fill> 
              <LinearGradient rotation="90"> 
                   <GradientEntry color="#000000" alpha="0.8"/> 
                   <GradientEntry color="#FFFFFF" alpha="0.8"/> 
              </LinearGradient> 
         </fill> 
    </Path> 
</Graphic> 
You can set the layoutDirection of the parent container on the Graphic tag directly; for example:
<s:Graphic layoutDirection='rtl'>

Flex mirrors the contents of the BitmapFill class when you set the property on the container. This can cause undesireable results when you set the layoutDirection property on an application that supports both RTL and LTR. To workaround this issue, you can create two versions of the graphic. Then create a custom skin for your control that uses the background image and use states to pick the right one depending on the value of the application's layoutDirection.

Coordinate systems

When using graphics, you specify the start point and end point of paths. These locations are represented as coordinate X/Y pairs such as (0,0). The default location for (0,0) is the upper left corner of the container that you are drawing in. If you change the layout direction, the coordinates, too, are mirrored. As a result, the coordinates (0,0) in a container with layoutDirection="rtl" refers to the upper right corner of the container, as the following example shows:
<?xml version="1.0" encoding="utf-8"?> 
<!-- mirroring/CoordinatesMirroring.mxml --> 
<s:Application 
    xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark"> 
 
    <s:layout> 
        <s:HorizontalLayout/> 
    </s:layout> 
 
    <fx:Script> 
        <![CDATA[        
            import mx.core.LayoutDirection;        
        ]]> 
    </fx:Script> 
 
     <mx:Panel title="LTR: from (0,0) to (100,100)" 
        height="75%" width="40%" layout="horizontal" 
        paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"> 
        <s:Group> 
           <s:Line xFrom="0" xTo="100" yFrom="0" yTo="100"> 
                 <s:stroke> 
                      <s:SolidColorStroke color="0x000000" weight="1"/> 
                 </s:stroke> 
           </s:Line> 
        </s:Group> 
     </mx:Panel> 
     <mx:Panel title="RTL: from (0,0) to (100,100)" layoutDirection="{LayoutDirection.RTL}" 
        height="75%" width="40%" layout="horizontal" 
        paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10"> 
        <s:Group> 
           <s:Line xFrom="0" xTo="100" yFrom="0" yTo="100"> 
                 <s:stroke> 
                      <s:SolidColorStroke color="0x000000" weight="1"/> 
                 </s:stroke> 
           </s:Line> 
        </s:Group> 
     </mx:Panel> 
</s:Application>

This same logic applies to layout coordinates. When you set the x and y position of a component in an LTR panel, the coordinates start at the upper left. If the panel's layout direction is RTL, the coordinates start in the upper right. However, calling the Menu.show(0,0) method will not pop up a menu at the top right, but rather, the top left because global coordinates are used.

If you use the localToGlobal() and globalToLocal() methods, or the DisplayObject transform property, you should be aware of the difference between a component's layoutMatrix and computedMatrix. The layoutMatrix is used to calculate the component's layout relative to its siblings. The computedMatrix incorporates the layoutMatrix and an IVisualElement's postLayoutTransformOffsets, which include the mirroring transform. The localToGlobal() and globalToLocal() methods and the transform.concatenatedMatrix property reflect the computed matrix.

To transform a point to global coordinates using only the layoutMatrix, use the MatrixUtil.getConcatenatedMatrix() method, as the following example shows:
var myGlobalPoint = MatrixUtil.getConcatenatedComputedMatrix(myIVisualElement).transformPoint(myPoint);

When working with coordinates, you should be aware of how the mirroring transform works. In an LTR application, X increases to the right and the origin is the upper left corner. In an RTL layout, X increases to the left and the origin is the upper right corner. This is accomplished internally by scaling the X-axis by -1 and translating the UIComponent by its width, after layout.

The effect of this mirroring transform is as follows:
element.x += width; 
element.scaleX *= -1;

All of the IVisualElement classes implement the mirroring transform using the same mechanism that is used by the offsets transform. That means that they are combined with the layout transform after layout has occurred. The transforms do not affect the actual values of the UIComponent's x and scaleX properties.

Mirroring DataGrid controls

You can use mirroring with a DataGrid control by setting the layoutDirection property on the application. Like most controls, the DataGrid control inherits this value. Setting the layout direction to RTL causes the columns to be arranged from right to left (column 0 is the right-most). This also aligns the sort arrows to the left of the header text. If the DataGrid is editable and the user clicks on a cell, the focus starts on the right side of the grid.

To align the text in the cells to the right, reverse the direction of the header text, and reverse the text in the individual cells of a DataGrid, you must also set the direction style property to "rtl". You can set this on a parent container or on the DataGrid itself.

The following example sets both the layoutDirection and direction properties to "rtl" so that the entire Spark DataGrid is mirrored:
<?xml version="1.0" encoding="utf-8"?> 
<!-- mirroring\MirroredDataGrid.mxml --> 
<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" 
   width="600" height="400" 
   layoutDirection="rtl" direction="rtl"> 
 
    <fx:Script> 
        <![CDATA[ 
            import mx.collections.ArrayCollection; 
            
            [Bindable] 
            private var dp:ArrayCollection = new ArrayCollection([ 
                {Artist:'Train', Album:'Drops of Jupiter', Price:13.99}, 
                {Artist:'Charred Walls of the Damned', Album:'Ghost Town', Price:8.99}, 
                {Artist:'Bleading Deacons', Album:'Rule the Night', Price:11.99}, 
                {Artist:'Three Stooges', Album:'Greatest Hits', Price:9.99} ]); 
        ]]> 
    </fx:Script>    
     
    <s:DataGrid id="myGrid" dataProvider="{dp}" 
        width="350" height="150"/>  
</s:Application>

Mirroring layouts

In a mirrored container, the roles of the left and right layout constraints are effectively reversed: the left constraint specifies the distance from the component's right edge to the right edge of the container, and the right constraint specifies the distance between the left edges.

Mirroring charting controls

To mirror charts, you set the layoutDirection property on the chart's parent container to RTL. Typically, you set it on the Application container. Charting controls inherit the value of this property set on the parent container.

In charts that are based on the CartesianChart class, such as the AreaChart, LineChart, and PlotChart controls, setting the layoutDirection property to "rtl" sets the point of origin at the lower right of the chart, rather than the lower left. For charts based on the PolarChart class, such as the PieChart control, setting the layoutDirection property to "rtl" has no effect on the point of origin.

The following example shows a chart that uses mirroring:
<?xml version="1.0" encoding="utf-8"?> 
<!-- mirroring\MirroredChart.mxml --> 
<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="srv.send()" 
       layoutDirection="rtl" 
       width="600" height="600"> 
    <s:layout> 
        <s:VerticalLayout/> 
    </s:layout> 
 
    <fx:Declarations> 
        <mx:HTTPService id="srv" url="http://aspexamples.adobe.com/chart_examples/expenses-xml.aspx"/> 
    </fx:Declarations> 
 
    <fx:Style> 
        @namespace s "library://ns.adobe.com/flex/spark"; 
        @namespace mx "library://ns.adobe.com/flex/mx"; 
        @namespace charts "mx.charts.chartClasses.*"; 
        
        charts|DataTip { 
            direction:rtl; 
            paddingRight:-10; 
            paddingLeft:5; 
        } 
    </fx:Style> 
    
    <s:Panel title="Column Chart"> 
        <s:layout> 
            <s:VerticalLayout/> 
        </s:layout> 
        <mx:ColumnChart id="myChart" dataProvider="{srv.lastResult.data.result}" showDataTips="true"> 
            <mx:horizontalAxis> 
                <mx:CategoryAxis id="haxis" categoryField="month" title="Month"/> 
            </mx:horizontalAxis> 
 
            <mx:verticalAxis>               
                <mx:LinearAxis id="vaxis" title="Amount"/> 
            </mx:verticalAxis> 
            
            <mx:series> 
                <mx:ColumnSeries 
                    xField="month" 
                    yField="profit" 
                    displayName="Profit"/> 
                <mx:ColumnSeries 
                    xField="month" 
                    yField="expenses" 
                    displayName="Expenses"/> 
            </mx:series> 
        </mx:ColumnChart> 
    </s:Panel> 
</s:Application> 
You should be aware of some minor differences in the way charting controls use spacing and alignment when the layoutDirection is "rtl". For example, to right align the contents of DataTips, set the DataTip direction style property to "rtl". You might also need to adjust the padding properties to get the alignment you want. For example:
@namespace charts "mx.charts.chartClasses.*"; 
charts|DataTip { 
	direction:rtl; 
	paddingRight:-10; 
	paddingLeft:5; 
}
In addition, when the layoutDirection property is set to "rtl":
  • Gutter padding — The left and right gutter style properties are reversed. The gutterLeft property changes the gutter padding on the right, and the gutterRight property changes the gutter padding on the left.

  • Axis labels — Setting labelAlign="left" aligns the label to the right, and labelAlign="right" aligns the label to the left.

  • Axis titles — The textIndent property is unaffected by the layoutDirection property. Axis titles do not support the textAlign property, so setting the layoutDirection property has no effect on this property.

Using the LocaleID class

The LocaleID class, available in Flash Player 10.1 and higher, provides methods and properties for using locale IDs. Locale IDs are strings that represent a particular locale. They can be useful when deciding whether to change the layout direction of an application.

The LocaleID class includes the isRightToLeft() method, which returns true if the currently set locale uses an RTL character code set, but otherwise returns false. You can use this method to set the values of the layoutDirection and direction properties. When you change locales in the following example, the application checks the isRightToLeft() method and sets the layoutDirection and direction properties on the Application object accordingly:
<?xml version="1.0" encoding="utf-8"?> 
<!-- mirroring\LocaleIDMirroringExample.mxml --> 
<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" 
            width="300" height="300" 
            layoutDirection="{localeBasedDirection}" 
            direction="{localeBasedDirection}" 
            creationComplete="updateSelection()"> 
    <fx:Script> 
        <![CDATA[ 
            import flash.globalization.LocaleID; 
            import mx.collections.ArrayCollection;          
            [Bindable] 
            public var localeBasedDirection:String; 
 
            [Bindable] 
            public var locID:LocaleID; 
 
            [Bindable] 
            public var myDP:ArrayCollection = new ArrayCollection( 
                [ {name:"US", locale:"en_US"}, 
                    {name:"Israel", locale:"he_IL"}, 
                    {name:"France", locale:"fr_FR"} ]); 
            
            private function updateSelection():void { 
                locID = new LocaleID(localeIdList.selectedItem.locale);                
                isRTLLabel.text = "RTL: " + locID.isRightToLeft().toString(); 
                getRegionLabel.text = "Region: " + locID.getRegion(); 
                getLanguageLabel.text = "Language: " + locID.getLanguage(); 
                
                if (locID.isRightToLeft()) { 
                    localeBasedDirection = "rtl"; 
                } else { 
                    localeBasedDirection = "ltr"; 
                } 
            } 
        ]]> 
    </fx:Script> 
 
    <s:Panel title="Select Locale" height="200" width="250"> 
        <s:layout> 
            <s:VerticalLayout paddingLeft="10" paddingRight="10" paddingTop="10"/> 
        </s:layout> 
        <s:VGroup> 
            <s:DropDownList id="localeIdList" selectedIndex="0" 
                dataProvider="{myDP}" 
                labelField="name" 
                change="updateSelection();"/>   
            <s:Label id="isRTLLabel"/> 
            <s:Label id="getRegionLabel"/> 
            <s:Label id="getLanguageLabel"/> 
        </s:VGroup> 
    </s:Panel> 
</s:Application>
This example requires classes in the flash.globalization.* package, which are available in the 10.1 or later playerglobal.swc file. When compiling this example, be sure to set the target player version to 10.1 or later. On the command-line, you can set the target Player version by using the target-player option; for example:
mxmlc -target-player=10.1 MyApp.mxml
In your applications, you will typically have some additional logic that sets the locale in your application, such as looking at the OS language code or accepting a user-configured setting. For information on setting locales in your application, see Setting the locale.

Mirroring with ToolTips and Error tips

The layoutDirection of the ToolTip class is same as the component that is attached to the ToolTip, or LTR, if the component does not implement the ILayoutDirectionElement interface.

Overlapping direction properties

Some components have a direction style property that is not related to text direction. These direction style properties typically take values not related to text direction. The compiler could throw an error if you try to set the direction property with these values. The following table lists these components:

Control

Description

mx.containers.Box

The direction property refers to the direction in which the container lays out its children.

mx.containers.FormItem

The direction property detemines whether the children of the FormItem are stacked vertically or placed horizontally.

mx.controls.ProgressBar

The direction property refers to the direction in which the bar expands towards completion. Possible values are "left" and "right". In general, you should set this to "right" when the application's layout is RTL.

mx.controls.scrollClasses.ScrollBar

The direction property detemines whether the scrollbar is for scrolling vertically or horizontally.

mx.controls.sliderClasses.Slider

The direction property detemines whether the slider is oriented vertically or horizontally. If you use an HSlider or VSlider, the control sets the value for you.

mx.containers.Tile

The direction property refers to the direction in which the container lays out its children.

mx.controls.listClasses.TileBase (which includes TileList and HorizontalList)

The direction property refers to the direction in which the container lays out its children.

Tips for using mirroring

Use the following tips when creating applications that use layout mirroring:
  • Avoid setting the layoutDirection and direction properties on individual components. Set them on the Application container.

  • Avoid using the alignment properties of individual components or blocks of text.

  • Avoid using absolute positioning.

  • If you want to mirror the contents of images (including icons) and videos, you should reverse the image or video in your image editing tools prior to importing them into your Flex application. The Spark and MX Image, BitmapImage, and VideoPlayer controls do not inherit the layoutDirection property from their parent container. The MX Image, Spark BitmapImage, and VideoDisplay controls do mirror their contents if you set layoutDirection on the control directly. The Spark Image control does not mirror its contents regardless of the value of its layout direction.

  • Spark text controls do not use layout mirroring. Instead, they support bidirectionality of text internally. As a result, the primitive text controls such as Label, RichText, and RichEditableText do not support the layoutDirection property. You typically set the direction style property to change the directionality of the text in these controls.

  • If you use text-based controls from the MX component set in your application, be sure to configure the compiler to use FTE to display the text. To do this on the command line, apply the MXFTEText.css theme file.

  • For Spark text controls or FTE text in MX components, use the values TextAlign.START and TextAlign.END for the textAlign property, rather than TextAlign.LEFT and TextAlign.RIGHT. Using START and END will work in the expected manner, regardless of the direction of the text.

  • In many components, navigating with the arrow keys changes depending on the directionality of the text. For example, the left arrow will navigate toward the beginning of the text and the right arrow key will navigate toward the end when the text is RTL.

Navigation

Using Flex » Enhancing usability

Adobe, Adobe Flash, and Adobe Flash Player are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States and/or other countries and are used by permission from Adobe. No other license to the Adobe trademarks are granted.