<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4548222296353391965</id><updated>2011-04-21T14:39:57.544-07:00</updated><category term='Custom Components'/><category term='PDF'/><category term='menus'/><category term='ActionScript'/><category term='MXML'/><category term='Acrobat'/><category term='Flex'/><category term='Adobe AIR'/><category term='Windows OS X'/><category term='FlexNativeMenu'/><category term='Events'/><category term='text conversion'/><category term='OS X'/><category term='component'/><category term='private'/><title type='text'>Itinerant Ramblings</title><subtitle type='html'>I've never been able to think of what I would want to blog about, and so I have never had a blog. However, I just finished my first Adobe AIR project, and thought it might be useful to post some of the things I learned along the way. For now, that's what this blog will be about. In time, perhaps it will grow to address other topics.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://smaskit.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://smaskit.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Sid Maskit</name><uri>http://www.blogger.com/profile/00728030058202172873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>7</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4548222296353391965.post-6682631778497648023</id><published>2008-08-10T11:47:00.000-07:00</published><updated>2008-08-10T13:50:28.479-07:00</updated><title type='text'>Possibly Useful Links</title><content type='html'>&lt;span style="font-size:100%;"&gt;These are links either recommended on the flexcoders mailing list, on other blogs, or that I have stumbled upon somewhere on the web. I am not vouching for these. This is primarily a list for my own reference. Obviously, if it is useful to somebody else, that is great.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Proxies&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.charlesproxy.com/"&gt;Charles&lt;/a&gt;&lt;br /&gt;&lt;a href="http://kevinlangdon.com/serviceCapture/"&gt;Service Capture&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.fiddlertool.com/Fiddler"&gt;Fiddler2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Diagramming Tools&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://www.sparxsystems.com.au/"&gt;Enterprise Architect&lt;/a&gt;: Drag a folder in, and it creates the class diagram for the code in it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Remote Desktop&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.darronschall.com/weblog/archives/000192.cfm"&gt;Flash VNC&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Flex &amp;amp; AIR Users Groups&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ria.meetup.com/10/"&gt;Flex Online&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.laflex.org/"&gt;Flex Los Angeles&lt;/a&gt;&lt;br /&gt;&lt;a href="http://laair.org/laair"&gt;AIR Los Angeles&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Jobs&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;a href="http://flexgigs.com/"&gt;Flexgigs&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Flex Issues Possibly Worth Voting for&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://bugs.adobe.com/jira/browse/FB-12296"&gt;Preserve Metadata&lt;/a&gt;&lt;br /&gt;&lt;a href="http://flexgigs.com/"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4548222296353391965-6682631778497648023?l=smaskit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smaskit.blogspot.com/feeds/6682631778497648023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4548222296353391965&amp;postID=6682631778497648023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/6682631778497648023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/6682631778497648023'/><link rel='alternate' type='text/html' href='http://smaskit.blogspot.com/2008/08/possibly-useful-links.html' title='Possibly Useful Links'/><author><name>Sid Maskit</name><uri>http://www.blogger.com/profile/00728030058202172873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4548222296353391965.post-2140585298831972184</id><published>2008-07-28T10:39:00.000-07:00</published><updated>2008-07-28T11:26:53.326-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ActionScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Events'/><category scheme='http://www.blogger.com/atom/ns#' term='Custom Components'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>addChild Component Instantiation In Table Form</title><content type='html'>In reading through the documentation on creating an advanced ActionScript component, I realized that it would be easier for me to understand if I had a more visual presentation of what happens when the addChild() method is called. So I have turned the "About the component instantiation lifecycle," section of "Creating and Extending Adobe Flex 3 Components" document (p. 134 of the PDF), into the table below.&lt;br /&gt;&lt;br /&gt;Within the table, time goes from top to bottom. Also I have use the following color coding to try to make things a little clearer:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt; &lt;li style="background-color: #ffffbb;"&gt;Dispatch Event&lt;/li&gt;&lt;br /&gt; &lt;li style="background-color: #ccffff;"&gt;Invalidation Method used to tell Flex framework to call a Render Method&lt;/li&gt;&lt;br /&gt; &lt;li style="background-color: #cccccc;"&gt;Render Method called by Flex Framework, not by components. These are the methods normally overriden when creating a custom ActionScript component, especially one that extends UIComponent.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;table width="100%" border="1" cellpadding="5"&gt;&lt;tr&gt;&lt;th style="border: 1px solid black; padding: 5px; text-align: left"&gt;Status&lt;/th&gt;&lt;th style="border: 1px solid black; padding: 5px; text-align: left"&gt;Flex&lt;/th&gt;&lt;th style="border: 1px solid black; padding: 5px; text-align: left"&gt;Container&lt;/th&gt;&lt;th style="border: 1px solid black; padding: 5px; text-align: left"&gt;Component&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;ActionScript: myContainer.addChild(myComponent);&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;parent = myContainer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;style = {computed by Flex}&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #ffffbb;"&gt;dispatch preinitialize event&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #cccccc;"&gt;createChildren()&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #ccffff;"&gt;invalidateProperties()&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #ccffff;"&gt;invalidateSize()&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #ccffff;"&gt;invalidateDisplayList()&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;all of the component's children have been initialized, but it has not been  sized or processed for layout.&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #ffffbb;"&gt;dispatch initialize event&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #ffffbb;"&gt;dispatch childAdd event&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #ffffbb;"&gt;dispatch initialize event&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;Start next render event&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #cccccc;"&gt;commitProperties()&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #cccccc;"&gt;measure() unless the user set component.height and   component.width&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #cccccc;"&gt;layoutChrome() if component is a Container&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #cccccc;"&gt;updateDisplayList()&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #ffffbb;"&gt;dispatch updateComplete event&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;dispatch additional render events if render methods called invalidation methods&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;last render event finishes&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;component is sized and processed for layout&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;visible = true&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #ffffbb;"&gt;dispatch creationComplete event&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;"&gt;&lt;/td&gt;&lt;td style="border: 1px solid black; padding: 5px;; background-color: #ffffbb;"&gt;dispatch updateComplete event&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;Note that the updateComplete event is dispatched whenever the layout, position, size, or other visual characteristic of the component changes and the component is updated for display. Thus it may fire a lot. For example, it will fire at least twice as part of adding a child component to a container.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4548222296353391965-2140585298831972184?l=smaskit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smaskit.blogspot.com/feeds/2140585298831972184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4548222296353391965&amp;postID=2140585298831972184' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/2140585298831972184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/2140585298831972184'/><link rel='alternate' type='text/html' href='http://smaskit.blogspot.com/2008/07/addchild-component-instantiation-in.html' title='addChild Component Instantiation In Table Form'/><author><name>Sid Maskit</name><uri>http://www.blogger.com/profile/00728030058202172873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4548222296353391965.post-5415219871899866674</id><published>2008-07-23T11:57:00.000-07:00</published><updated>2008-07-23T18:32:56.806-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MXML'/><category scheme='http://www.blogger.com/atom/ns#' term='component'/><category scheme='http://www.blogger.com/atom/ns#' term='private'/><title type='text'>Making MXML Subcomponent Private</title><content type='html'>Recently someone asked on the flexcoders mailing list how to make a subcomponent private when working in MXML. The short answer is that this cannot be done since MXML does not support access control settings: i.e. anything declared in MXML is public, and cannot be changed to private, protected or internal. However, things are not that simple.&lt;br /&gt;&lt;br /&gt;Let's assume that we have the following setup:&lt;br /&gt;&lt;br /&gt;MyComponent.mxml extends VBox (or any other container).&lt;br /&gt;MyComponent has a TextInput MXML tag within it.&lt;br /&gt;MyApplication.mxml has a MyComponent MXML tag within it.&lt;br /&gt;&lt;br /&gt;Our goal is to have the TextInput component treated as a private property of MyComponent: i.e. it should be accessible within MyComponent, but not from MyApplication.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Solution I: Omit Id Attribute&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The simplest way to achieve this would be to not have an id attribute for the TextInput control within MyComponent. If the TextInput control does not have an id, there will be no way for MyApplication to access it. (For purposes of this discussion, we are not worried about the fact that the TextInput control will be accessible as a child of MyComponent in the display list.)&lt;br /&gt;&lt;br /&gt;The obvious drawback of this approach is that the TextInput control will also be inaccessible within MyComponent: i.e. it will be impossible to bind to properties of the TextInput control, or to use script to set or get any of the TextInput control's properties. In cases where that limitation is acceptable, omitting an id tag is an easy way to achieve privacy.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Solution II: Coding Convention&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A second way to achieve rough equivalency with privacy is through coding conventions. For example, one could decide as an organization that any property that began with an underscore would be respected as private. So if in MyComponent we declared our TextInput like this&lt;br /&gt;&lt;pre&gt;&amp;lt;mx:TextInput id="_myText" /&amp;gt;&lt;/pre&gt;&lt;br /&gt;It would be considered inappropriate within MyApplication to have code such as the following:&lt;br /&gt;&lt;pre&gt;myComponent._myText.text&lt;/pre&gt;&lt;br /&gt;Of course, within MyComponent, it would be considered appropriate to have code such as the following:&lt;br /&gt;&lt;pre&gt;_myText.text&lt;/pre&gt;&lt;br /&gt;or&lt;br /&gt;&lt;pre&gt;this._myText.text&lt;/pre&gt;&lt;br /&gt;With this approach, it is now possible within MyComponent to bind to the properties of _myText, as well as to get and set its properties. Although this approach has the obvious disadvantage that the compiler will not enforce it, it could go a long way toward achieving the desired end. &lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Solution III: Proxy&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A more complicated, but more powerful solution is to use a proxy variable. In this approach, the TextInput control does not have an id attribute. Instead, it triggers an event which calls a function that assigns a reference to the TextInput control to a private variable. Within MyComponent, our code might look like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;mx:Script&amp;gt;&lt;br /&gt;    &amp;lt;![CDATA[&lt;br /&gt;        [Bindable]&lt;br /&gt;        private var textProxy:TextInput;&lt;br /&gt;       &lt;br /&gt;        private function subDone(event:Event):void {&lt;br /&gt;            textProxy = event.target as TextInput;&lt;br /&gt;        }&lt;br /&gt;    ]]&amp;gt;&lt;br /&gt;&amp;lt;/mx:Script&amp;gt;&lt;br /&gt;&amp;lt;mx:TextInput creationComplete="subDone(event);" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Within MyComponent, one can bind to properties of the TextInput control, as well as set or get its properties, by using the textProxy variable. For example, we could add a text control which will mirror what is typed in the TextInput control by adding the following code:&lt;br /&gt;&lt;pre&gt;&amp;lt;mx:Text text="{textProxy.text}" /&amp;gt;&lt;/pre&gt;&lt;br /&gt;In essence, we have assigned an id property to the TextInput control, but one that is private. Thus, within MyApplication, there is no way to access the TextInput control since it has no id, and since textProxy is private.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Solution IV: the [Exclude] Metadata Tag&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;See the blog post at &lt;a href="http://blog.ashier.com/2008/03/25/hiding-properties-in-flex-components/"&gt;http://blog.ashier.com/2008/03/25/hiding-properties-in-flex-components/&lt;/a&gt;, including my comment on the limits of this approach.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4548222296353391965-5415219871899866674?l=smaskit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smaskit.blogspot.com/feeds/5415219871899866674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4548222296353391965&amp;postID=5415219871899866674' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/5415219871899866674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/5415219871899866674'/><link rel='alternate' type='text/html' href='http://smaskit.blogspot.com/2008/07/making-mxml-subcomponent-private.html' title='Making MXML Subcomponent Private'/><author><name>Sid Maskit</name><uri>http://www.blogger.com/profile/00728030058202172873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4548222296353391965.post-6553458177121602922</id><published>2008-07-22T23:01:00.000-07:00</published><updated>2008-07-23T12:58:25.205-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ActionScript'/><category scheme='http://www.blogger.com/atom/ns#' term='text conversion'/><title type='text'>An ActionScript Class for Converting Between HTML and Plain Text</title><content type='html'>I've written an HtmlConverter class which allows ActionScript to convert between HTML and plain text, in both directions, without using regular expressions.&lt;br /&gt;&lt;br /&gt;The main functionality is provided by the TextInput component since it automatically converts plain text to HTML, and vice versa. The tricky part is that this conversion only happens when the TextInput control is on the stage. (After looking at the code for the TextInput control, my sense is that the conversion is done by the flash player, not by the control.) In order to minimize the impact of using the control for the conversion, the HtmlConverter object adds a TextInput control to the stage, waits for it to perform the conversion, and then immediately removes it from the stage.&lt;br /&gt;&lt;br /&gt;Since we have to wait for the TextInput control to be fully placed on the stage, and to perform the conversion, the result of the conversion will not be available until at least one frame after the conversion is requested. This means that interactions with the HtmlConverter object have to be asynchronous: i.e. they have to use events rather than return values from functions.&lt;br /&gt;&lt;br /&gt;Here is the file HtmlConverter.as:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;package com.craftyspace.utilities {&lt;br /&gt;   import flash.events.EventDispatcher;&lt;br /&gt; &lt;br /&gt;   [Event(name="textConverted", type="flash.events.Event")]&lt;br /&gt;   public class HtmlConverter extends EventDispatcher {&lt;br /&gt;       import flash.events.Event;&lt;br /&gt;       import mx.events.FlexEvent;&lt;br /&gt;       import mx.controls.TextInput;&lt;br /&gt;       import mx.core.Application;&lt;br /&gt;       import mx.binding.utils.ChangeWatcher;&lt;br /&gt;     &lt;br /&gt;       public static const TEXT_CONVERTED:String = "textConverted";&lt;br /&gt;     &lt;br /&gt;       [Bindable(event="htmlTextChanged")]&lt;br /&gt;       public function get htmlText():String {&lt;br /&gt;           return this.component.htmlText;&lt;br /&gt;       }&lt;br /&gt;     &lt;br /&gt;       [Bindable(event="textChanged")]&lt;br /&gt;       public function get text():String {&lt;br /&gt;           return this.component.text;&lt;br /&gt;       }&lt;br /&gt;     &lt;br /&gt;       private var component:TextInput = new TextInput();&lt;br /&gt;     &lt;br /&gt;       public function HtmlConverter() {&lt;br /&gt;           super(null);&lt;br /&gt;       }&lt;br /&gt;     &lt;br /&gt;       public function toHtml(plain:String):void {&lt;br /&gt;           this.component.text = plain;&lt;br /&gt;           this.component.addEventListener(FlexEvent.UPDATE_COMPLETE, onComplete);&lt;br /&gt;           Application.application.addChild(this.component);&lt;br /&gt;       }&lt;br /&gt;     &lt;br /&gt;       public function toPlain(HTML:String):void {&lt;br /&gt;           this.component.htmlText = HTML;&lt;br /&gt;           this.component.addEventListener(FlexEvent.UPDATE_COMPLETE, onComplete);&lt;br /&gt;           Application.application.addChild(this.component);&lt;br /&gt;       }&lt;br /&gt;     &lt;br /&gt;       private function onComplete(event:FlexEvent):void {&lt;br /&gt;           component.removeEventListener(FlexEvent.UPDATE_COMPLETE, onComplete);&lt;br /&gt;           Application.application.removeChild(this.component);&lt;br /&gt;           this.dispatchEvent(new Event("htmlTextChanged"));&lt;br /&gt;           this.dispatchEvent(new Event("textChanged"));&lt;br /&gt;           this.dispatchEvent(new Event("textConverted"));&lt;br /&gt;       }&lt;br /&gt;     &lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Within ActionScript, one would use the class's TEXT_CONVERTED event to get the results, like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   private function init():void {&lt;br /&gt;       var converter:HtmlConverter = new HtmlConverter();&lt;br /&gt;       converter.addEventListener(HtmlConverter.TEXT_CONVERTED, onTextConverted);&lt;br /&gt;       converter.toPlain('&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;my&amp;lt;/b&amp;gt; text&amp;lt;/p&amp;gt;');&lt;br /&gt;   }&lt;br /&gt;     &lt;br /&gt;   private function onTextConverted(event:Event):void {&lt;br /&gt;       trace((event.target as HtmlConverter).text);&lt;br /&gt;       trace((event.target as HtmlConverter).htmlText);&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Alternatively, instead of handling the HtmlConverter.TEXT_CONVERTED event, one can bind to either the text or htmlText property of an HtmlConverter object:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;mx:Script&amp;gt;&lt;br /&gt;    &amp;lt;![CDATA[&lt;br /&gt;        import com.craftyspace.utilities.HtmlConverter;&lt;br /&gt;        &lt;br /&gt;        [Bindable]&lt;br /&gt;        private var converter:HtmlConverter;&lt;br /&gt;&lt;br /&gt;        private function init():void {&lt;br /&gt;            converter = new HtmlConverter();&lt;br /&gt;            converter.toPlain('&amp;lt;p&amp;gt;&amp;lt;b&amp;gt;my&amp;lt;/b&amp;gt; text&amp;lt;/p&amp;gt;');&lt;br /&gt;        }&lt;br /&gt;    ]]&amp;gt;&lt;br /&gt;&amp;lt;/mx:Script&amp;gt;&lt;br /&gt;&amp;lt;mx:Text text="{'html: ' + converter.htmlText}" /&amp;gt;&lt;br /&gt;&amp;lt;mx:Text text="{'plain: ' + converter.text}" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that the above code stores the HtmlConverter object in a persistent variable that is declared bindable. If one does not do this, the MXML controls will not be able to bind to the HtmlConverter's properties.&lt;br /&gt;&lt;br /&gt;One thing that cannot be done with an HtmlConverter object is to declare it as an MXML tag. This is because the HtmlConverter class is not a descendent of the UIComponent class.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Caveats&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Although it was interesting going through the process of writing this class, I suspect that most of the time it would make more sense to use regular expressions.&lt;br /&gt;&lt;br /&gt;Putting a TextInput control on the stage for a couple of frames each time it does a conversion has two costs. It requires the flash player to re-render twice: once to display the TextInput control, and once to remove it from the display. It may be the case that this could be mitigated by setting styles on the control, but I have not explored that.&lt;br /&gt;&lt;br /&gt;The second cost is that the conversion must be dealt with asynchronously using events. Needless to say, this is significantly less convenient than a situation where one can do something like the following:&lt;br /&gt;&lt;br /&gt;myPlaintext:String = myRegexBasedConverter.toPlain(myHtmlText);&lt;br /&gt;&lt;br /&gt;and&lt;br /&gt;&lt;br /&gt;myHtmlText = myRegexBasedConverter.toHtml(myPlaintext);&lt;br /&gt;&lt;br /&gt;Of course, if someone wants not just any HTML, but the HTML which would be rendered by the flash player, then this class might be useful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4548222296353391965-6553458177121602922?l=smaskit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smaskit.blogspot.com/feeds/6553458177121602922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4548222296353391965&amp;postID=6553458177121602922' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/6553458177121602922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/6553458177121602922'/><link rel='alternate' type='text/html' href='http://smaskit.blogspot.com/2008/07/actionscript-class-for-converting.html' title='An ActionScript Class for Converting Between HTML and Plain Text'/><author><name>Sid Maskit</name><uri>http://www.blogger.com/profile/00728030058202172873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4548222296353391965.post-2924408218218984856</id><published>2008-07-15T11:44:00.001-07:00</published><updated>2008-07-15T11:48:01.742-07:00</updated><title type='text'>Storing Dates in the AIR SQLite Database</title><content type='html'>One thing that took me awhile to figure out is how to use dates with the SQLite database. It turns out that Adobe modified SQLite so it now supports a DATE data type. This is actually documented, but is a little bit buried. So far as I can tell, it is not in any of the PDF's that provide the standard documentation for flex and air, but only appears in an appendix to the language reference. For complete details, see the "SQL support in local databases" appendix of the ActionScript 3 Language and Components Reference.&lt;br /&gt;&lt;br /&gt;In a nutshell, there is a DATE datatype which corresponds to the Date ActionScript class. You can directly insert a date ActionScript object into a database field of the DATE type. Similarly, when you select data from a DATE field of the database, it will be returned as an ActionScript date object. Finally, because the data will come out of the database as a date object, you can then upload it to a remote database, using AMF, and it should correctly map to the date data type on the remote database. I've only done this with SQL Server, but it worked correctly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4548222296353391965-2924408218218984856?l=smaskit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smaskit.blogspot.com/feeds/2924408218218984856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4548222296353391965&amp;postID=2924408218218984856' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/2924408218218984856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/2924408218218984856'/><link rel='alternate' type='text/html' href='http://smaskit.blogspot.com/2008/07/storing-dates-in-air-sqlite-database.html' title='Storing Dates in the AIR SQLite Database'/><author><name>Sid Maskit</name><uri>http://www.blogger.com/profile/00728030058202172873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4548222296353391965.post-7576078132222484569</id><published>2008-07-10T17:15:00.000-07:00</published><updated>2008-07-10T17:26:37.457-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PDF'/><category scheme='http://www.blogger.com/atom/ns#' term='OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='Acrobat'/><category scheme='http://www.blogger.com/atom/ns#' term='Adobe AIR'/><title type='text'>Avoid Spaces in PDF File Names in Adobe AIR on OS X</title><content type='html'>Another odd quirk of an Adobe AIR application running in OS X is that it will not display a PDF if there is a space in the file name.&lt;br /&gt;&lt;br /&gt;I had a menu item which would pop up a new native window, and display a PDF in that window by setting the location of an HTML component to the PDF file. This would work fine on Windows, but the window would launch with a black screen on OS X if there was a space in the filename of the PDF.&lt;br /&gt;&lt;br /&gt;Removing the space fixed the problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4548222296353391965-7576078132222484569?l=smaskit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smaskit.blogspot.com/feeds/7576078132222484569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4548222296353391965&amp;postID=7576078132222484569' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/7576078132222484569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/7576078132222484569'/><link rel='alternate' type='text/html' href='http://smaskit.blogspot.com/2008/07/avoid-spaces-in-pdf-file-names-in-adobe.html' title='Avoid Spaces in PDF File Names in Adobe AIR on OS X'/><author><name>Sid Maskit</name><uri>http://www.blogger.com/profile/00728030058202172873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4548222296353391965.post-7603854547072768928</id><published>2008-07-10T16:40:00.000-07:00</published><updated>2008-07-10T17:18:51.207-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows OS X'/><category scheme='http://www.blogger.com/atom/ns#' term='FlexNativeMenu'/><category scheme='http://www.blogger.com/atom/ns#' term='Adobe AIR'/><category scheme='http://www.blogger.com/atom/ns#' term='menus'/><title type='text'>FlexNativeMenu and Mac OS X</title><content type='html'>I don't know whether this is an Apple standard, or just a quirk, but Adobe AIR menus need to be a little more complicated to work in OS X.&lt;br /&gt;&lt;br /&gt;In Windows, one can have a menu which does not have any sub-items, but which simply works as if it were a button in the menu bar. For example, when my application ran in Windows, it would display the following top-level menus: Observations, Account, Schools, Reports, and Help. The Account menu did not contain any items, but clicking Account would load the account page.&lt;br /&gt;&lt;br /&gt;However, in OS X, it would display Observa... and the rest of the menu bar would be blank. Further, clicking the Observations menu would not work.&lt;br /&gt;&lt;br /&gt;After much trial and error, I discovered that OS X did not like the single-item menus.&lt;br /&gt;&lt;br /&gt;To get around this, I had to give the Account menu a sub-item so that clicking that menu would open it, and one could then click on the only item in the menu. In other words, one would open the Account menu, and then click on the Profile item within that menu. Once I made that change, everything worked the same on both Windows and OS X.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4548222296353391965-7603854547072768928?l=smaskit.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://smaskit.blogspot.com/feeds/7603854547072768928/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4548222296353391965&amp;postID=7603854547072768928' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/7603854547072768928'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4548222296353391965/posts/default/7603854547072768928'/><link rel='alternate' type='text/html' href='http://smaskit.blogspot.com/2008/07/flexnativemenu-and-mac-os-x.html' title='FlexNativeMenu and Mac OS X'/><author><name>Sid Maskit</name><uri>http://www.blogger.com/profile/00728030058202172873</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
