<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Programmification</title>
	<atom:link href="http://dafrito.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://dafrito.wordpress.com</link>
	<description>The Many Howto's of Aaron Faanes</description>
	<lastBuildDate>Mon, 02 Mar 2009 23:52:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='dafrito.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Programmification</title>
		<link>http://dafrito.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://dafrito.wordpress.com/osd.xml" title="Programmification" />
	<atom:link rel='hub' href='http://dafrito.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Java IO</title>
		<link>http://dafrito.wordpress.com/2009/02/01/java-io/</link>
		<comments>http://dafrito.wordpress.com/2009/02/01/java-io/#comments</comments>
		<pubDate>Sun, 01 Feb 2009 17:37:29 +0000</pubDate>
		<dc:creator>Aaron Faanes</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dafrito.wordpress.com/?p=49</guid>
		<description><![CDATA[Java&#8217;s IO classes offer a surprising amount of functionality; it&#8217;s kind of surprising that they seem unappreciated in practice. The documentation on them rarely extends beyond simple file I/O. File I/O is usually what you use them for, of course, but the package offers alot more than simply reading and writing to files. Streams are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=49&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Java&#8217;s IO classes offer a surprising amount of functionality; it&#8217;s kind of surprising that they seem unappreciated in practice. The documentation on them rarely extends beyond simple file I/O. File I/O is usually what you use them for, of course, but the package offers alot more than simply reading and writing to files.</p>
<h3>Streams are the Fundamental Abstraction of java.io.*</h3>
<p>java.io consists of around 50 separate classes, and you can divide them up in a few ways. Almost all deal with the input or output of a <strong>stream</strong><em>. </em>A stream really isn&#8217;t anything formal; it&#8217;s just a sequence of bytes that you interpret as data.</p>
<p>Streams may not necessarily be intuitive in some ways, though, so I&#8217;ll go over some of the concepts. Understanding these is critical to avoiding alot of the weird situations that you can find yourself in with streams.</p>
<h3>Streams have no Implied Structure</h3>
<p>The data contained inside a stream has no real indication of its structure; it&#8217;s up to the programmer to read it correctly. Java provides two sets of classes to deal with the two common forms of data: <strong>InputStream</strong> or <strong>OutputStream</strong> interpret data merely as bytes<strong>. Reader </strong>or <strong>Writer</strong><em> </em>assume your data is textual, and they interpret data as a series of characters. These four abstract classes are the core of the IO package. Other classes supplement these to allow a wider range of expression and abstraction when dealing with data.</p>
<h3>The Length of a Stream May Not Be Known</h3>
<p>An easy analogy for streams is that they are like arrays. The stream contains a sequence of units of data, the programmer reads them in bits and pieces, and from them, the programmer gains useful information about something.</p>
<p>The analogy breaks down when it comes to finding a length. If you imagine an array, its size is known and fixed. You can access any piece of it at any time, instantly. The entire thing is immediately available. On the other hand, a stream&#8217;s size is not known. It&#8217;s assumed to end at some point, but may very well not depending on its source.</p>
<p>To belabor this point (and probably appear very patronizing), arrays are crayon boxes. You can pull out any given crayon without having to deal with any other crayons. Streams are like coke machines. You can access one unit of coke per request. Many different functions make this more convenient and faster, but in the end, you (or the methods you&#8217;re calling) are stuck dealing with one coke can at a time. You don&#8217;t know how many coke cans there are in the machine until the machine tells you it doesn&#8217;t have any more.</p>
<p>Of course, we&#8217;re talking about streams in the purest sense; for our examples, we know the length of the stream because we provide the data explicitly. The length of files may also be known since the array that we&#8217;re &#8220;streaming&#8221; from is local. So while a stream has no concept of its length, that doesn&#8217;t necessarily mean we never know its length. It just means that streams have no concept of their own size.</p>
<h3>Streams Do Not Need To Immediately Return; They May Block</h3>
<p>The power of streams is in their abstraction. Streams are merely sequences of data. The format is freeform, the length is not a concern, and the source need not be local. This flexibility has its limitations, however. The format must be explicitly given to the user of the stream, an unknown length requires care on the part of the programmer, and non-local sources may take a long time to return.</p>
<p>I&#8217;ve mentioned the first two, but the third point definitely requires some mention. A stream is dependent on its source for information. The speed at which that source provides our stream with data is not known, but we are ultimately dependent on that speed. While we&#8217;re waiting for that data, we must wait. This state of waiting is known as blocking &#8211; we&#8217;re blocking any further progress while we wait.</p>
<p>For an example, I&#8217;ll return to the crayon box/coke machine example. Getting a crayon from the crayon box is dependent only on how fast you yourself retrieve it. There&#8217;s no waiting because between the two concepts of &#8220;wanting the crayon&#8221; and &#8220;having the crayon,&#8221; you&#8217;re working towards the latter.</p>
<p>If you&#8217;re waiting in line at a coke machine, there&#8217;s still the two concepts of &#8220;wanting a coke&#8221; and &#8220;having a coke.&#8221; However, between these two concepts is a large amount of doing nothing. You&#8217;re waiting for other people to do stuff; you&#8217;re not working towards the goal directly. The coke machine and its users are blocking you from getting your coke.</p>
<p>There&#8217;s a couple clarifications to be made here when relating it to streams. First, the concept of blocking can occur with local things; accessing the hard drive is very expensive compared to accessing memory directly. In this example, your request for data on the hard drive will block until that data is available to use. Even if your request is the only one active, you&#8217;ll still have to wait for that process to succeed. Blocking simply means &#8216;the program cannot continue to execute until this method call successfully returns.&#8217;</p>
<h3>Blocking Resources Do Not Always Need to Block</h3>
<p>Blocking isn&#8217;t really an exact term. Waiting for a webpage to load is apparent blocking; you can&#8217;t use the webpage until it&#8217;s fully loaded. (Of course, there&#8217;s incremental loading of pages, but just work with me here.) You can see and feel the waiting. On the other hand, file I/O may not be perceivable. Large files, maybe, but small ones won&#8217;t. Memory access, processor cache access are all used with completely inapparent, but existent, wait-times between request and response.</p>
<p>These waits are blocking in the conceptual sense. Of course, we talk about blocking when it comes to network and file I/O but don&#8217;t talk about it when it comes to memory I/O. There are two reasons for this: The first is convention &#8211; file and network access take long enough to perceptibly block.</p>
<p>The other is more arcane: File and network access do not offer themselves exclusively to the requester. They may be servicing many concurrent requests at once, so we might be queued. These non-exclusive places require may require some form of blocking before they&#8217;re actually doing any work at all on our request. This is not true to exclusive resources; these service one person exclusively and constantly.</p>
<p>This last point is more important than it appears: The fact that non-exclusive resources <em>may</em> block means that they&#8217;re considering blocking resources. Whether they block on any given request is irrelevant. This marks a distinction between the concept of &#8216;blocking&#8217; and the action of &#8216;blocking.&#8217; I may not be blocking, but if I can block on some requests, I am a blocking resource.</p>
<p>Understanding blocking will save you alot of trouble when it comes to streams (or any sort of synchronous request). The fact that streams block means that stream is a potential bottleneck. A set of classes in <em>java.io.*</em> exist to minimize the strain these streams may cause to your performance.</p>
<h3>read() Returns One Unit of Data from a Stream</h3>
<p>The public interfaces of these classes mirror each other. The input classes mirror the output classes and the byte-based classes mirror their character-based ones, so learning one part of it lets you transfer that knowledge to any other set of classes. Very useful. I&#8217;ll start with <em>read() </em>and <em>write().<br />
</em></p>
<p>Derivatives of <strong>Reader</strong> and <strong>InputStream</strong> function in the exact same way when dealing with simple I/O. Here&#8217;s an example to show this:</p>
<pre>// Read one character from the stream
private static void doSomeCharIO() throws IOException {
    Reader reader = new StringReader("This is a happy string.");
    int firstValue = reader.read();
    System.out.println(firstValue + " " + (char)firstValue);
    // Output: "84 T"
}</pre>
<p>This straightforward example is probably the smallest IO one can do. We create a <strong>StringReader</strong> which lets us treat a string as a stream. We then call <code>reader.read()</code> to get the first character. Notice that we don&#8217;t actually get a <code>char</code> back. Instead, we&#8217;re given an <code>int</code> that we have to cast.</p>
<p>One reason this doesn&#8217;t return a <code>char</code> is to be consistent with <strong>InputStream</strong>. (The other reason is negative values are indicative of errors; I&#8217;ll talk more later) At any rate, the lesson here is this: When using any input stream or reader, <code>read()</code> returns a single unit of data (a byte or character depending on the class used) that is always in terms of an integer. Casting that integer to a byte or character, respectively, will get you the data you want.</p>
<p>To prove my point that these two classes are basically the same, here&#8217;s the above example but using an <strong>InputStream</strong>:</p>
<pre>// Read one byte from the stream
private static void doSomeByteIO() throws IOException {
    byte[] byteArray = new byte[] { 'T', 'h', 'i' };
    InputStream stream = new ByteArrayInputStream(byteArray);
    int firstValue = stream.read();
    System.out.println(firstValue + " " + (char)firstValue);
    // Output: "84 T"
}</pre>
<p>Since we&#8217;re using a different format, we need to use different classes. However, other than that, the two examples are identical.</p>
<h3>write() is Symmetric to its Reading Counterpart</h3>
<p>Write does what you&#8217;d expect: It writes a single byte or character. The signature of the simplest method is <code>void write(int b)</code>. This signature is identical for both <strong>OutputStream</strong> and <strong>Writer</strong>. Since the potential range of values in a single <code>char</code> or <code>byte</code> is less than an <code>int</code>, you don&#8217;t need to explicitly cast them. Here&#8217;s the code for both, just to demonstrate:</p>
<pre>private static void doSomeCharWriting() throws IOException {
    int theValueOfT = (int)'T'; // Should be 84.
    Writer writer = new StringWriter();
    writer.write(theValueOfT);
    System.out.println(writer); // Prints 'T'
}

private static void doSomeByteWriting() throws IOException {
    int theValueOfT = (int)'T'; // Should be 84.
    OutputStream stream = new ByteArrayOutputStream();
    stream.write(theValueOfT);
    System.out.println(stream); // Also prints 'T'
}</pre>
<p>As you can see, it&#8217;s straightforward. We instantiate the correct class, write our value, then can send it directly to <code>System.out</code>. It should probably be noted that neither <strong>OutputStream</strong> nor <strong>Writer</strong> guarantee toString() will work in this way for all their derivatives; retrieving the value of a written stream may vary from class to class.</p>
<p>I&#8217;m getting a little self-conscious about the rate at which I&#8217;m introducing this stuff. I figure these mechanics seem fairly self-evident; my intention is to demonstrate these fundamentals fully before moving on to more complicated stuff. My hope is that this foundation will serve you well when you&#8217;re trying to understand the much more complicated stuff later, as you&#8217;ll have this to fall back on.</p>
<p>But after all, dealing with streams in terms of single units is not exactly common place. You&#8217;ll probably be dealing in terms of groups of bytes or characters. You may abstract even further and deal with streams in terms of primitives and objects. If your data has some parsing involved, you may need to navigate through the stream. Java&#8217;s facilities will serve you will in all these cases.</p>
<h3>A Stream Can Work With Arrays of Data</h3>
<p><code>read()</code> and <code>write()</code> can understandably be given arrays as well as single units. The character-based and byte-based stream classes differ only in what type of array they&#8217;re expecting, so I&#8217;ll only demonstrate one such type here. This example will use a <strong>CharArrayReader</strong> just because we haven&#8217;t used one yet; there&#8217;s no motive beyond that.</p>
<pre>private static void doSomeSimpleCharReading() throws IOException {
    Reader reader = new CharArrayReader("This could be a character array!".toCharArray());
    char[] charArray = new char[4];
    reader.read(charArray);
    System.out.println(charArray); // Prints "This"
    reader.read(charArray);
    System.out.println(charArray); // Prints " cou"
}</pre>
<p>This little tidbit fills our <em>charArray</em> with as many bytes as it can hold (in this case, just 4). Notice that since we&#8217;re just dealing with data, the array we give it has no concept of being &#8220;filled&#8221; or not. You can see here that when we call <em>read()</em> again, we overwrite our previous contents. This can be fairly convenient when you&#8217;re dealing with data that comes in known quantities.</p>
<p>On the other hand, having it destroy your array every time it reads may not be what you want. Furthermore, the <strong>Reader</strong> will fill the array with <em>n</em> bytes, where <em>n</em> is the length of your array. You may not necessarily want it to take that many, but don&#8217;t want to make many arrays to handle all the different sizes. Java has more advanced capabilities to deal with this sitaution, but for the moment, the idea is useful to show the final version of <em>write()</em>:</p>
<pre>private static void doSomeExactCharReading() throws IOException {
    Reader reader = new CharArrayReader(
        "This could be a character array!".toCharArray()
    );
    char[] charArray = new char[10];
    reader.read(charArray, 0, 4);
    System.out.println(charArray); // Roughly prints "This"
    reader.read(charArray, 5, 5);
    System.out.println(charArray); // Roughly prints "This coul"
}</pre>
<p>This version of read expects a <em>char[]</em> array for its first argument, like the second form. It also expects an offset and a length. These will be used to determine where to start writing in the array you&#8217;ve given it, and how many characters to fill. Notice that you&#8217;ll be given an <em>IndexOutOfBoundsException</em> if you try to overflow the array.</p>
<h3>Streams Do Not Panic When Reaching the End Of A Stream</h3>
<p>At some point, you&#8217;ll reach the end of your stream. Many languages throw an exception when this occurs. They provide no other means to determine whether you&#8217;ve reached this point, so you&#8217;re always having to catch it. This condition makes for clever code (since your EOF, or <em>end-of-file</em> for convenience here, logic is separated), but it&#8217;s hardly exceptional. I imagine it is merely the cleverness that justifies using the exception. This is an act grates on me.</p>
<p>Luckily for us, Java reacts calmly in the face of EOF. A tempting solution is to use a stream method called <em>available()</em>. This returns an integer that represents <em>an estimate of how many bytes that can be read without blocking on the next invocation of a method for this input stream.</em> It is <em><strong>NOT </strong></em>necessarily the length of the stream; as I mentioned earlier, streams are coke machines. We don&#8217;t necessarily know how long the stream is because <em>the stream </em>may not know. For example, one can&#8217;t open a file, make an array of the size that <em>available()</em> returns, and live happily ever after assuming that&#8217;s the full length of the file.</p>
<p>The definition I heartlessly stole from the API doc&#8217;s is very deliberately phrased. [[ To be continued... ]]</p>
<h3>Streams Can Optionally Provide Mark/Reset Functionality</h3>
<p>[[ To be continued... ]]</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dafrito.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dafrito.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dafrito.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dafrito.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dafrito.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dafrito.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dafrito.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dafrito.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dafrito.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dafrito.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dafrito.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dafrito.wordpress.com/49/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dafrito.wordpress.com/49/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dafrito.wordpress.com/49/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=49&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dafrito.wordpress.com/2009/02/01/java-io/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/98e75f40b07fc2dddbc700e609bbcea2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dafrito</media:title>
		</media:content>
	</item>
		<item>
		<title>Swing, AWT, and SWT</title>
		<link>http://dafrito.wordpress.com/2009/01/30/swing-awt-swt/</link>
		<comments>http://dafrito.wordpress.com/2009/01/30/swing-awt-swt/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 05:14:11 +0000</pubDate>
		<dc:creator>Aaron Faanes</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://dafrito.wordpress.com/?p=28</guid>
		<description><![CDATA[I have heard many people discuss these GUI toolkits as though they are equal competitors. I&#8217;d like to state unequivocally that they are not. Use Swing. Use Swing. Of course, what kind of advice would that be without backing it up with a long post? Without further ado, here&#8217;s details on the pros and cons [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=28&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I have heard many people discuss these GUI toolkits as though they are equal competitors. I&#8217;d like to state unequivocally that they are <em>not.</em> Use Swing. Use Swing.</p>
<p>Of course, what kind of advice would that be without backing it up with a long post? Without further ado, here&#8217;s details on the pros and cons of all three Java GUI toolkits, and how they compare.</p>
<h1>AWT vs. Swing</h1>
<p>This is one of those presumably old debates. It used to be relevant around ten years ago, but Swing and Java have both so drastically improved that there&#8217;s no reason to use AWT. Furthermore, the debate is somewhat moot since Swing is heavily based <em>on</em> AWT; a more apt title would be AWT vs. AWT with Swing-like sprinkles on top.</p>
<p>In fact, you can think of Swing as the successor to AWT rather than a competing toolkit. If you trace the class hierarchy of most Swing classes, you&#8217;ll find it has a AWT ancestor. Swing uses vast swaths of AWT functionality, so much that it&#8217;s safe to say Swing is built on top of AWT.</p>
<h3>Heavyweight components have a native counterpart; lightweight components do not</h3>
<p>Of course, both provide a set of ready-to-use GUI components, like buttons, menus, etc. The discussion of which toolkit to use usually means which set of GUI components to use, since the underlying framework in AWT is used directly by Swing.</p>
<p>It&#8217;s been commonly said that AWT&#8217;s components are &#8220;heavyweight&#8221; and Swing&#8217;s are &#8220;lightweight.&#8221; These terms do not necessarily mean either component is worse in terms of functionality or performance. They refer to whether a GUI component is &#8220;backed&#8221; by a <em>native peer.</em> You can think of a native peer as the &#8220;real&#8221; GUI component that the host platform would use normally. In other words, a native peer is the C or C++ class that you&#8217;d instantiate directly if you were programming in C/C++ exclusively.</p>
<p>The problem with this idea is that native peers necessarily vary between host platforms. Since AWT bases its functionality off these hosts, it is forced to the lowest common denominator of capability. This meant that relatively common components, like tables and trees, could not be included in AWT.</p>
<p><em>It should be mentioned that neither toolkit actually has a monopoly on either lightweight or heavyweight components. AWT is capable of creating lightweight components, and Swing must use heavyweight components when creating top-level components.</em></p>
<h3>Swing has no native peers; it is pure Java</h3>
<p>The limitations of AWT&#8217;s functionality led directly to Swing. Swing&#8217;s components are lightweight; they are pure Java and do not rely on the host platform. Swing&#8217;s components are therefore consistent in behavior across platforms.</p>
<p>Java&#8217;s aim is to be seamless, both to the developer and the end-user. The appearance of components should ordinarily look like the host platform&#8217;s. To solve this, Swing separated the behavior of components from their appearance. The appearance side is broken into many libraries, each implementing a different <em>look and feel</em> for each host platform.</p>
<h3>Swing is, roughly, a superset of AWT</h3>
<p>Swing is hardly written from scratch. Many components in Swings deliberately mirror their AWT counterparts. Other features use AWT classes directly. For example, all Swing components are derived from some AWT class, typically java.awt.Component.</p>
<p>Swing lies on top of AWT, adding a richness that the constraints of AWT did not allow. This freedom gives Swing the existing power of AWT with the flexibility to extend it as the designers and developers see fit. AWT&#8217;s components, on the other hand, are bound by the slow evolution of various host platforms.</p>
<h3>There is no debate; use Swing</h3>
<p>People usually see these two frameworks and imagine that there must be some choice to be made. After all, both are still around. However, there is no real choice. Swing is the successor to AWT. The reason AWT is still mentioned is because Swing uses an incredible amount of it.</p>
<p>It should be mentioned that there are no great performance gains anymore between AWT and Swing. Initially, AWT was respectably faster than Swing since native peers do allow performance gains in some cases. However, it&#8217;s been awhile since those times, and Swing and its companion libraries (like Java2D) have been optimized heavily. Performance is not a reason to use AWT over Swing.</p>
<h1>SWT vs. Swing</h1>
<p>Discussing Java toolkits should necessarily include this third-party toolkit, known as SWT or <em>Standard Widget Toolkit<strong>. </strong></em>Popularized by its use in Eclipse, SWT can be thought of as a rewritten AWT, but with a Swing-fallback. SWT uses native peers if available but can fall back to pure Java components if a certain platform doesn&#8217;t support the features required. The reason for this extends beyond simple performance gains; SWT exposes a far greater amount of low-level functionality to the programmer. The intention is to allow a highly customizable interface for developers.</p>
<h3>SWT is not standard</h3>
<p>SWT has many forces working against it. For one, its name belies the fact that it&#8217;s not standard. SWT is a third-party toolkit not available on a vanilla Java install, nor is it necessarily compatible wherever Java can be run. Since it relies heavily on native integration, a SWT library must be written specifically for each native platform. The problem caused with this isn&#8217;t that you&#8217;ll be out of luck trying to run it on your machine (SWT already has most OS&#8217;s covered). Since SWT intentionally exposes alot of low-level capability, the experience may not be symmetric across these platforms. Reconciling these issues is left to the developer.</p>
<h3>Swing&#8217;s continuing maturity removes many justifications for SWT</h3>
<p>SWT seems more like an impatient solution to the problems of the first-party Java GUI toolkits than a real attempt to innovate GUI development in Java. Its low-level emphasis may be useful in certain cases, but I&#8217;d be hardpressed to see a case where SWT exposes something that Swing is unable to do.</p>
<p>Now, this last point is only more recently true. Swing did lack some expected features, such as system tray access, the capability to open a native browser or email client, and so forth. However, these things have since been remedied by their inclusion in AWT. Swing&#8217;s (and Java&#8217;s) performance problems have also diminished significantly, further reducing the need for native peers and low-level exposure.</p>
<h3>Low-level exposure works against expectations in Java</h3>
<p>On a fuzzier note, I find that SWT simply doesn&#8217;t <em>feel</em> like Java. This is aggravated by the fact that Java already has a GUI toolkit, so the standards have already been set. SWT&#8217;s design goals of exposing the meat of the interface you&#8217;re building on seems to work against the design goals of Java itself. SWT finds you having to do such heinous things as explictly disposing resources when you&#8217;re done with them.</p>
<p>Of course, explicitly disposing resources theoretically allows you to perform faster and cleaner than the garbage collector would otherwise allow. I am somehow reminded of standard versus automatic transmissions. I am also reminded of Pareto&#8217;s principle. If garbage collection is your bottleneck, you&#8217;re doing something wrong (or very odd).</p>
<p>Now, the problem I&#8217;m getting at here is not that SWT requires explicit resource disposal. Indeed, anything that&#8217;s touching the underlying native interface must concern themselves with disposal. The problem is that low-level access <em>as a rule</em> simply isn&#8217;t necessary in GUI toolkits.</p>
<p>It feels like someone missed programming GUIs in C/C++ and decided to write something in Java that mimics it as much as possible. They knew such a thing would be laughed out of existence, so they made Eclipse use it and named it something that makes it sound like it&#8217;s official.</p>
<h3>There is no debate; use Swing</h3>
<p>In all seriousness, SWT did solve some shortcomings with Swing in the past. But as Swing continues to improve, SWT&#8217;s reasons for existence deteriorate. SWT will not get you magnitudes of performance increase on a noticeable level. Nor will its low-level programming model afford you customization that you can&#8217;t do in Swing. I simply don&#8217;t believe there are valid, wide-scale arguments anymore for using it over Swing.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dafrito.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dafrito.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dafrito.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dafrito.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dafrito.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dafrito.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dafrito.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dafrito.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dafrito.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dafrito.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dafrito.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dafrito.wordpress.com/28/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dafrito.wordpress.com/28/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dafrito.wordpress.com/28/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=28&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dafrito.wordpress.com/2009/01/30/swing-awt-swt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/98e75f40b07fc2dddbc700e609bbcea2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dafrito</media:title>
		</media:content>
	</item>
		<item>
		<title>Convention, Configuration, and Customization</title>
		<link>http://dafrito.wordpress.com/2009/01/28/convention-configuration-customization/</link>
		<comments>http://dafrito.wordpress.com/2009/01/28/convention-configuration-customization/#comments</comments>
		<pubDate>Wed, 28 Jan 2009 23:40:49 +0000</pubDate>
		<dc:creator>Aaron Faanes</dc:creator>
				<category><![CDATA[Theory]]></category>

		<guid isPermaLink="false">http://dafrito.wordpress.com/?p=14</guid>
		<description><![CDATA[The Scenario, and its Hairy Implications Imagine you&#8217;re writing a class for some framework. You expect a healthy amount of people to use it; it&#8217;s not disposable. Designing even a simple class for this case can be painful, usually because your design motivations conflict with one another. Let&#8217;s approach these from the viewpoints of various [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=14&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h2>The Scenario, and its Hairy Implications</h2>
<p>Imagine you&#8217;re writing a class for some framework. You expect a healthy amount of people to use it; it&#8217;s not disposable. Designing even a simple class for this case can be painful, usually because your design motivations conflict with one another. Let&#8217;s approach these from the viewpoints of various people:</p>
<p><strong>You.</strong> You<strong>, </strong>being the developer, want to write a useful class. You&#8217;re hoping to write it fairly quickly, and you don&#8217;t want to get stuck correcting mistakes and additions to it</p>
<p><strong>The Casual User.</strong> He needs the functionality your class provides, but he doesn&#8217;t want to waste alot of time trying to use it. The functionality this provides is tangential to what he&#8217;s working on. As a developer, this user is highly predictable in how he&#8217;s using your class, and you want to minimize time and code spent for this individual.</p>
<p><strong>The One-Off Guy. </strong>He wants the functionality of your class, but will need to do some configuration to get it to work like he wants to. He&#8217;s not stretching the definition of your class very much, so ideally the effort required should be trivial and obvious.</p>
<p><strong>The Academic.</strong> He sees potential in your class to perform something that you&#8217;re not likely to anticipate. He&#8217;ll probably want to subclass your class, or plug in a subclassed component that your class uses, to get what he wants.</p>
<p>These three individuals all stress different parts of the system. The casual user loves convention; he is, by definition, conventional. Catering to him will make your class seem monolithic. Favoring the one-off guy instead will stress the configuration of your class. His interests will involve indirect access of some small piece of your system.</p>
<p>These two individuals don&#8217;t usually clash. Adding configuration to help the one-off guy usually means providing a default for the casual. In many ways, they&#8217;re the same person: Slight variance in the design and defaults of the class will make casual users have to be one-off guys and vice versa. If you can be aware of this balance, you can tune your defaults to favor the majority.</p>
<h3>Dealing with Academics</h3>
<p>Academics are fringe-cases. They may be interested in pieces of your system that aren&#8217;t typically touched by other users. For example, they may not be interested in the conventional use of your system, but the workflow that your class provides. A classic example would be a socket stream: he may want to use the interface that the stream provides, but write it to use an entirely different medium, such as accessing a file locally.</p>
<p>The academic may seem like a trivial concern, since they&#8217;re heavily outnumbered by the first two. However, academics stress the design of your class directly. Adding file I/O directly to the stream class makes socket-specific functionality senseless. In the face of this, you have a few options:</p>
<ul>
<li><strong>Do nothing.</strong> You may choose to rely on the intelligence of your users to ignore socket-specific functionality if they&#8217;re dealing with files. While easiest for the developer, it&#8217;s rude to make users have to guess how your class should work, especially when your interface isn&#8217;t consistent.</li>
<li><strong>Retrofit the Conventional Case.</strong> You may be able to get away with fitting the new functionality into existing methods. In this case, a file stream is &#8220;connecting&#8221; to a file like a socket stream would connect to a wayward socket. This makes the interface seem consistent, but it really isn&#8217;t. You&#8217;re still relying on the fact that users will use your class conventionally, and you&#8217;ve actually done them a disservice by hiding the true intentions of your class.</li>
<li><strong>Subclass!</strong> What the academic seems to want is a new class that uses the functionality of the parent while extending it to his own needs. Subclassing clearly indicates there is a specialization of functionality present, and both options are clear on their own. This seems like the safest solution, but it has hidden dangers in how the breakdown is performed. You can&#8217;t just subclass your socket stream, since doing so leaves you with the same consequences as the first two options (Which one you&#8217;re left with depends on details of your implementation). While you have a separate class that works with files, you&#8217;re still left with a ambiguous interface that people are stuck using.</li>
</ul>
<p>Now, this is solvable too. If you remove socket-specific stuff and place it in its own subclass, and make the original stream abstract, it&#8217;s pretty obvious what you&#8217;re doing.</p>
<h3>The Problems of Subclassing</h3>
<p>The problem I see with this is proliferation. A FileStream and a SocketStream class may themselves be extended to provide specialized functionality. If they are, then the subclasser must decide which type of stream he wishes to specialize. If he tries to do the Right Thing and be as flexible as possible, he must subclass every permutation of the Stream class. So now you have Stream, FileStream, SocketStream, SpecializedFileStream, SpecializedSocketStream. You&#8217;re also forced to implement the full interface of Stream (Even if that interface just throws exceptions) since you&#8217;re masquerading as a stream.</p>
<p>Wrapping the streams through composition cleans up the hierarchy. You&#8217;d have instead your base Stream classes, and your specializer that takes a stream as an argument to its constructor. Composition is a clean alternative to subclassing that doesn&#8217;t muck up the class hierarchy. As a rule, flat class hierarchies are much better than deep ones. The problem here is that it&#8217;s difficult to justify <em>not</em> subclassing. After all, your Specializer class is essentially a stream. The only difference is that it&#8217;s not a stream like the original stream is.</p>
<p><strong>Refactor?</strong> The problem isn&#8217;t solved by composition or inheritance because the original class is ill-defined and should be refactored. We organized the functionality of the stream into one class because it makes semantic sense to do so: We connect to the socket, send and receive data, then close it. File I/O involves opening a file, reading and writing data, then closing it. Our problems arise because we have two responsibilities, both potentially flexible, in the same class. When this happens, you&#8217;ll have this problem of class proliferation. Composition masks the problem, but inhibits the benefits of the class hierarchy.</p>
<p>What we should do is separate the stream class into its two natural components: The connection, and the encoding. We&#8217;ll steal a UNIX tradition and treat files and sockets as fundamentally the same thing. This probably isn&#8217;t that big a jump for anyone. The strength here is separating the management of the connection from the encoding of data. Instead of making a Stream class for every type of connection, we separate them both entirely into Encoders and Locations. A stream is a composition of these two. A file and a socket are both subclasses of Location, and a specializer and our original Stream class are both encoders. A stream is, for the most part, a convenience class that is given these two components and manages the events of both.</p>
<h3>Why Good Decomposition Is Better</h3>
<p>One could probably argue that this solution is overly complex. After all the work, we&#8217;ll have the Encoder, Location interfaces, and the Stream class. Two classes implement Location, File and Socket. On top of that, we&#8217;ll have our DefaultEncoder and SpecializedEncoder to solve the original problem. That&#8217;s five classes and 2 interfaces. That&#8217;s more than any other solution. However, hear me out: Classes that are decomposed well are better than fewer classes that are decomposed poorly. We found and separated the two responsibilities that were causing us problems earlier, and now we&#8217;re left with two hierarchys that are both very specific in their purpose. As a consequence, I&#8217;ll imagine they&#8217;re very easy to test. Problems with connection management are isolated inside the Location class, and problems during encoding are isolated within the other. Both classes are also extensible to add new methods of encoding or destinations to which to send.</p>
<p>Even further, there is no coupling between the two class hierarchies. While we&#8217;ve constructed them to use them together, there&#8217;s nothing keeping us from using these two hierarchies elsewhere. The fact that they are separate encourages this possbility. Sensible factory methods (presumably in Stream) will allow the conventional user to use our Stream uninhibited by the newfound flexibilty that we&#8217;ve provided him. The logical decomposition of these responsibilities allows the Academic to extend this class with ease. A set of preconstructed locations and encodings will allow the one-off user easy configuration of the stream.</p>
<h3>Why OOP Matters</h3>
<p>I should stress one final point: The goal of OOP <em>is <strong>not </strong></em>code reuse. We benefit from code reuse when we do good OOP, but reusing code does not mean we are practicing good design. The real goal of OOP is to allow decomposition of responsibility in a fashion that closely resembles how we work and think. This contrasts with functional programming, where decomposition is done along the preference of the machine. The original design of the stream class resembles this &#8211; we hardcoded the semantics of the conventional use in the design of the class, instead of hardcoding the responsibility of each concept into the classes.</p>
<p>This probably isn&#8217;t very clear &#8211; a functional approach to decomposition would yield classes that mirror data structures.  The Stream class is defined by how we&#8217;d use it, and its functions expose that conventional use. This works as long as we use the class conventionally. However, when we move beyond that, our class becomes a barrier to progress. It&#8217;s difficult to extend a class that exposes this kind of interface. A good responsibility-driven approach to decomposition will yield classes that allow extension and facilitate easy maintenance and testing.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dafrito.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dafrito.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dafrito.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dafrito.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dafrito.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dafrito.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dafrito.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dafrito.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dafrito.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dafrito.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dafrito.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dafrito.wordpress.com/14/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dafrito.wordpress.com/14/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dafrito.wordpress.com/14/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=14&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dafrito.wordpress.com/2009/01/28/convention-configuration-customization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/98e75f40b07fc2dddbc700e609bbcea2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dafrito</media:title>
		</media:content>
	</item>
		<item>
		<title>ScrolledComponent</title>
		<link>http://dafrito.wordpress.com/2008/04/28/scrolledcomponent/</link>
		<comments>http://dafrito.wordpress.com/2008/04/28/scrolledcomponent/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 15:00:06 +0000</pubDate>
		<dc:creator>Aaron Faanes</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[ScrollControlBase]]></category>
		<category><![CDATA[Component]]></category>
		<category><![CDATA[Scrolling]]></category>

		<guid isPermaLink="false">http://dafrito.wordpress.com/?p=11</guid>
		<description><![CDATA[In writing the previous article on extending ScrollControlBase, I mentioned that the current implementation could be used as a generic scroller for any component. However, in keeping the article on topic, I didn&#8217;t really delve into how that would be done. I ended up writing it, so here&#8217;s a link to the complete source of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=11&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In writing <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-its-internals-and-design-philosophy/">the previous article on extending ScrollControlBase</a>, I mentioned that the current implementation could be used as a generic scroller for any component. However, in keeping the article on topic, I didn&#8217;t really delve into how that would be done. I ended up writing it, so here&#8217;s a link to <a href="http://files.dafrito.com/ScrolledComponent.as">the complete source of ScrolledComponent</a>. <span id="more-11"></span></p>
<p>Some details on its implementation:</p>
<p><strong>Feeding <code>ScrolledComponent</code> Content</strong></p>
<p>ScrolledComponent accepts any <code>DisplayObject</code> or subclass thereof as its <code>content</code> property. This will be the component that will be scrolled. All Flex components extend <code>UIComponent</code>, which itself extends <code>DisplayObject</code> so you can throw whatever you want in there. The component we made in the &#8220;Extending ScrollControlBase&#8221; article would be implemented like so:</p>
<pre>var scrolled:ScrolledComponent = new ScrolledComponent();
var image:Image = new Image();
image.source = this.someDisplayAsset; // This would be some embedded image, or a URL to one.
scrolled.content = image;
this.addChild(scrolled);</pre>
<p>You could (And probably would) do the same thing in MXML via setting the <code>content</code> property. For convenience, <code>ScrolledComponent</code> defaults to using the <code>content</code> property in MXML, so you can just define the <code>content</code> property inline, like so:</p>
<pre>&lt;local:ScrolledComponent width="100%" height="100%"&gt;
    &lt;mx:image source="{this.someDisplayAsset}"/&gt;
&lt;/local:ScrolledComponent&gt;</pre>
<p>You can also use it as a item renderer, since it implements <code>IDataRenderer</code>, and can give it a class to use as content via <code>data</code> property.</p>
<p><strong>Changing How Content Is Displayed</strong></p>
<p>ScrolledComponent implements the following styles and properties affecting its display:</p>
<ul>
<li><strong><code>verticalAlign</code> and <code>horizontalAlign</code></strong> &#8211; Affects where content is displayed inside the scrolled content. These work like they do in <code>VBox</code> and <code>HBox</code>. Currently, there is no <code>center</code> or <code>middle</code> alignment, since the use case for those is rare, but adding them wouldn&#8217;t be too difficult in your own code. (If you need them, just request it here and I&#8217;ll throw them in.)</li>
<li><strong><code>verticalPinPolicy</code></strong> &#8211; Affects how vertical scrolling works. If this is set to true, the list will stick to the bottom as content is added. Scrolling up will &#8220;unpin&#8221; the document, but if it is scrolled back to the bottom, it will be stick again. This behavior emulates IRC clients and chat message windows.I didn&#8217;t add a <code>horizontalPinPolicy</code>, but if the need arises, I&#8217;ll do so. If you wish to implement it, it would act the same as the vertical, but obviously in the horizontal direction. (Again, if you need them, just request so in the comments, and I&#8217;ll add it.)</li>
</ul>
<p>I hope this is useful for anyone looking for a generic scroller, and again, here&#8217;s <a href="http://files.dafrito.com/ScrolledComponent.as">the link to the source.</a> Please post any comments or bug findings here, and I&#8217;ll see to them. I&#8217;m using this component in my own projects, so I hopefully should run into any before you do.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dafrito.wordpress.com/11/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dafrito.wordpress.com/11/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dafrito.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dafrito.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dafrito.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dafrito.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dafrito.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dafrito.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dafrito.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dafrito.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dafrito.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dafrito.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dafrito.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dafrito.wordpress.com/11/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dafrito.wordpress.com/11/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dafrito.wordpress.com/11/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=11&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dafrito.wordpress.com/2008/04/28/scrolledcomponent/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/98e75f40b07fc2dddbc700e609bbcea2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dafrito</media:title>
		</media:content>
	</item>
		<item>
		<title>Extending ScrollControlBase: The Workflow</title>
		<link>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-the-workflow/</link>
		<comments>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-the-workflow/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 11:11:48 +0000</pubDate>
		<dc:creator>Aaron Faanes</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[ScrollControlBase]]></category>
		<category><![CDATA[Component]]></category>
		<category><![CDATA[Scrolling]]></category>
		<category><![CDATA[Workflow]]></category>

		<guid isPermaLink="false">http://dafrito.wordpress.com/?p=8</guid>
		<description><![CDATA[This post is the last page of a 4-post series on &#8220;Extending ScrollControlBase.&#8221; It describes the completed widget, along with providing a checklist on how to properly implement a component extending ScrollControlBase. Here&#8217;s a list of links to the other pages in this article: 1. Its Internals and Design Philosophy 2. Displaying the Scrollbars 3. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=8&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post is the last page of a 4-post series on &#8220;Extending ScrollControlBase.&#8221; It describes the completed widget, along with providing a checklist on how to properly implement a component extending ScrollControlBase.<span id="more-8"></span> Here&#8217;s a list of links to the other pages in this article:</p>
<p>1. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-its-internals-and-design-philosophy/"> Its Internals and Design Philosophy</a><br />
2. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-displaying-the-scrollbars/"> Displaying the Scrollbars</a><br />
3. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-getting-scrolling-to-work/"> Getting Scrolling to Work</a><br />
4. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-the-workflow/">The Workflow</a></p>
<p>Implementing scrolling is an intuitive process, involving merely a mask, updateDisplayList, and an event listener. We&#8217;ve implemented from scratch, a scrolled image viewer, but the code is simple enough to be expanded to scroll any arbitrary content (Matter of fact, we&#8217;ve actually gone out of the way to make it be image-specific).</p>
<p>To summarize, here&#8217;s the generic workflow you&#8217;ll use to implement ScrollControlBase in your own components:</p>
<ol>
<li><strong>Extend ScrollControlBase</strong> &#8211; extend the class, set the policies to any defaults as you see fit.</li>
<li><strong>Implement <code>commitProperties</code></strong> &#8211; Clean up and remove any old content. Add the new content, and set its <code>mask</code> to <code>maskShape</code></li>
<li><strong>Implement <code>measure</code></strong> &#8211; Get the default size of your content, and add <code>viewMetrics</code> to it, assigning the calculated width and height to <code>measuredWidth</code> and <code>measuredHeight</code>, respectively.</li>
<li><strong>Implement <code>updateDisplayList</code></strong> &#8211; Draw your component if necessary. Its position is given by <code>viewMetrics</code>&#8216; <code>left</code> and <code>top</code> properties, subtracting any current <code>horizontalScrollPosition</code> and <code>verticalScrollPosition</code>. Finally, call <code>setScrollBarProperties(totalColumns, visibleColumns, totalRows, visibleRows)</code> with the intended visible area, along with the total visible area.</li>
<li><strong>Implement <code>scrollHandler</code></strong> &#8211; Check if 1.) your content is valid, 2.) this ScrollEvent isn&#8217;t from a TextField and thus incompatible with your component, and 3.) that this is a finished scroll if <code>liveScrolling</code> is <code>false</code>. If so, then position your content according to the new positions.</li>
</ol>
<p>And that&#8217;s it. If you find out scrolling is expensive, then it&#8217;s probably due to alot of content having to be redrawn. ScrollControlBase enables you to use its scrolling capability and its mask independently, so you can produce your own mask over a smaller area, if necessary (ListBase, and therefore, all List-like deriatives of it) use this in many cases to produce a faster rendering by as much as 25% (As it says in the source). As always, the source code provided in the Flex SDK is invaluable in letting you come up with ways to build components and optimizing it as necessary.</p>
<p>Here&#8217;s <a href="http://files.dafrito.com/ScrollingImage.as">a link to the complete source of what we wrote</a>. It&#8217;s free for you to use, modify, or do whatever.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dafrito.wordpress.com/8/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dafrito.wordpress.com/8/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dafrito.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dafrito.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dafrito.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dafrito.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dafrito.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dafrito.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dafrito.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dafrito.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dafrito.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dafrito.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dafrito.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dafrito.wordpress.com/8/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dafrito.wordpress.com/8/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dafrito.wordpress.com/8/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=8&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-the-workflow/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/98e75f40b07fc2dddbc700e609bbcea2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dafrito</media:title>
		</media:content>
	</item>
		<item>
		<title>Extending ScrollControlBase: Getting Scrolling to Work</title>
		<link>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-getting-scrolling-to-work/</link>
		<comments>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-getting-scrolling-to-work/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 10:39:08 +0000</pubDate>
		<dc:creator>Aaron Faanes</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[ScrollControlBase]]></category>
		<category><![CDATA[Component]]></category>
		<category><![CDATA[Scrolling]]></category>

		<guid isPermaLink="false">http://dafrito.wordpress.com/?p=7</guid>
		<description><![CDATA[This post is the third page of a 4-post series on &#8220;Extending ScrollControlBase.&#8221; It discusses how to use ScrollControlBase&#8217;s setScrollBarProperties method and how to implement its scrollHandler event listener. Here&#8217;s some links to the other pages in this article: 1. Its Internals and Design Philosophy 2. Displaying the Scrollbars 3. Getting Scrolling to Work 4. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=7&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post is the third page of a 4-post series on &#8220;Extending ScrollControlBase.&#8221; It discusses how to use ScrollControlBase&#8217;s <code>setScrollBarProperties</code> method and how to implement its <code>scrollHandler</code> event listener.<span id="more-7"></span> Here&#8217;s some links to the other pages in this article:<br />
1. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-its-internals-and-design-philosophy/"> Its Internals and Design Philosophy</a><br />
2. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-displaying-the-scrollbars/"> Displaying the Scrollbars</a><br />
3. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-getting-scrolling-to-work/"> Getting Scrolling to Work</a><br />
4. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-the-workflow/">The Workflow</a></p>
<p>Our component now has a functional implementation of UIComponent&#8217;s methods, but is still missing the ability to scroll. It turns out this requires two, separate, but equally important methods: <code>scrollHandler</code> and <code>setScrollBarProperties</code>. Lets talk them over in turn:</p>
<p><strong>Working with <code>setScrollBarProperties</code></strong></p>
<p>This method is the brains behind ScrollControlBase. Every time your content changes sizes, this method will need to be called. The signature looks like this:</p>
<pre>protected function setScrollBarProperties(
    totalColumns:int, visibleColumns:int,
    totalRows:int, visibleRows:int):void</pre>
<p>Notice that the property names are pixel-independent. You simply describe how many rows your content has in total, and how many are visible, with the same for the columns. What a row or column is is dependent on your component. In many cases, these are pixels, but for some cases, a row could be a literal row of data as in a table, or a line of text. TextArea makes each rows a line of text, and each column a pixel, so your own rows and columns don&#8217;t necessarily have to be of the same unit. Calling this method will set the properties of the scrollbars as necessary to resize to the size of your data.</p>
<p>Our call is probably the simplest call this function can be, and is done at the end of <code>updateDisplayList</code>:</p>
<pre>this.setScrollBarProperties(
    this.currentImage.width,
    unscaledWidth - edgeMetrics.left - edgeMetrics.right,
    this.currentImage.height,
    unscaledHeight - edgeMetrics.top - edgeMetrics.bottom
);</pre>
<p>Remember that edgeMetrics is the size of the padding, borders, and viewed scrollbars. Our <code>totalRows</code> and <code>totalColumns</code> is simply the dimensions of our image. The visible rows and columns is the unscaled dimensions given to us as parameters, with the applicable edgeMetrics properties subtracted from each.</p>
<p>With this single call, the scroll bars will be properly shown or hidden, with the thumb (The selectable part) the right size to show all the content. You should call this whenever the size of your content changes, but since that&#8217;s usually coupled with a call to <code>updateDisplayList</code>, you&#8217;re safe to leave it only there in most cases. You shouldn&#8217;t call it in <code>measure</code>, though, since you won&#8217;t necessarily have correct unscaled dimensions yet.</p>
<p>Of course, proper scrollbars without event handlers are only eye candy. Let&#8217;s make them live.</p>
<p><strong>Implementing <code>scrollHandler</code></strong></p>
<p><code>scrollHandler</code> is an event listener implemented originally in ScrollControlBase. It receives updates whenever either scroll bar is moved. (It will even fire when <code>liveScrolling</code> is false, so handling whether this variable is set should be done inside the function). You should respond to scrolling events here.</p>
<p>Our implementation is mostly boilerplate:</p>
<pre>
override protected function scrollHandler(event:Event):void {
  // Immediately return if there's no image.
  if(!this.currentImage)
    return;

  // Return if it's not a ScrollEvent. This is for TextField scroll events bubbling up that
  // we wouldn't understand.
  if(!(event is ScrollEvent))
    return;

  // And finally, if we're not liveScrolling, and we're in the middle of scrolling, return.
  if (!liveScrolling &amp;&amp; ScrollEvent(event).detail == ScrollEventDetail.THUMB_TRACK)
    return;

  super.scrollHandler(event);

  this.currentImage.x = this.viewMetrics.left + -this.horizontalScrollPosition;
  this.currentImage.y = this.viewMetrics.top + -this.verticalScrollPosition;
}
</pre>
<p>There&#8217;s the three return if-statements. Each are commented, so I won&#8217;t mention them further here. The call to <code>super.scrollHandler(event)</code> will update the horizontal and vertical scroll positions stored inside ScrollControlBase.</p>
<p>Finally, the two calls move our image in the negative direction of the current position. These two lines are all it takes to implement scrolling in most cases, and with those two lines, you&#8217;ll have a functioning scrolling image.</p>
<p>(We add the viewMetrics <code>left</code> and <code>top</code> properties to keep our image flush with the edges of the border, otherwise we&#8217;d show a border-thickness worth of background when we&#8217;re at the bottom, and clip a border-thickness&#8217; worth of image when we&#8217;re at the top.)</p>
<p>It might be asked why we don&#8217;t call invalidateDisplayList() instead inside scrollHandler, and ideally, that would be what we would do. But in this case, we&#8217;re safe to just update the values directly here, and not invoke the overhead associated with a full cycle of validation.</p>
<p>Read on to the next post to read <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-the-workflow/">the summary of what we&#8217;ve accomplished</a>, along with a cheat sheet on how to implement basic scrolling in any of your components.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dafrito.wordpress.com/7/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dafrito.wordpress.com/7/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dafrito.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dafrito.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dafrito.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dafrito.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dafrito.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dafrito.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dafrito.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dafrito.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dafrito.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dafrito.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dafrito.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dafrito.wordpress.com/7/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dafrito.wordpress.com/7/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dafrito.wordpress.com/7/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=7&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-getting-scrolling-to-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/98e75f40b07fc2dddbc700e609bbcea2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dafrito</media:title>
		</media:content>
	</item>
		<item>
		<title>Extending ScrollControlBase: Displaying the Scrollbars</title>
		<link>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-displaying-the-scrollbars/</link>
		<comments>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-displaying-the-scrollbars/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 09:44:15 +0000</pubDate>
		<dc:creator>Aaron Faanes</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[ScrollControlBase]]></category>
		<category><![CDATA[Component]]></category>
		<category><![CDATA[Scrolling]]></category>
		<category><![CDATA[UIComponent]]></category>

		<guid isPermaLink="false">http://dafrito.wordpress.com/?p=6</guid>
		<description><![CDATA[This post is the second of a 4-post series on &#8220;Extending ScrollControlBase.&#8221; It discusses how to override UIComponent&#8217;s validation methods in order to display the scrollbars provided with ScrollControlBase. Here&#8217;s some links to the other pages in this article: 1. Its Internals and Design Philosophy 2. Displaying the Scrollbars 3. Getting Scrolling to Work 4. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=6&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This post is the second of a 4-post series on &#8220;Extending ScrollControlBase.&#8221; It discusses how to override UIComponent&#8217;s validation methods in order to display the scrollbars provided with ScrollControlBase.<span id="more-6"></span> Here&#8217;s some links to the other pages in this article:<br />
1. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-its-internals-and-design-philosophy/"> Its Internals and Design Philosophy</a><br />
2. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-displaying-the-scrollbars/"> Displaying the Scrollbars</a><br />
3. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-getting-scrolling-to-work/"> Getting Scrolling to Work</a><br />
4. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-the-workflow/">The Workflow</a></p>
<p>Working with ScrollControlBase revolves around two things: Getting the mask to work right, and getting the scroll bars to function correctly with your image. We&#8217;ll cover each in turn in a simple example: Getting an image that&#8217;s viewed with a ScrollControlBase.</p>
<p>Our example component has a skeleton like this:</p>
<pre>
package {
  import mx.core.ScrollControlBase;

  public class ScrollingImage extends ScrollControlBase {
    public function ScrollingImage() {
      super();
      this.horizontalScrollPolicy = "auto";
    }
  }
}
</pre>
<p>That code by itself gives you essentially a ScrollControlBase directly. It gives you the scrolling properties and methods of ScrollControlBase, but applies no mask to its children at all, so adding any components will result in them being unsized unless explicitly sized, in which case they will occlude the border.</p>
<p>One thing of note is the setting of <code>horizontalScrollPolicy</code>. Scroll policies are really easy and have three possible values: <code>off</code>, <code>on</code>, or <code>auto</code>. <code>off</code>never shows scroll bars, <code>on</code> always does, and auto does only when there&#8217;s content needing to be scrolled. By default, <code>verticalScrollPolicy</code> is set to <code>auto</code>, and <code>horizontalScrollPolicy</code> is set to <code>off</code>. We set it to <code>auto</code> here since it&#8217;s as likely we&#8217;ll need to scroll horizontally as it is vertically.</p>
<p>For our component, the image being displayed is assumed to be an embedded asset, which are of type <code>Class</code>, so the getter and setters look like this:</p>
<pre>
    public class ScrollingImage extends ScrollControlBase {

    // Constructor and imports omitted for brevity
    protected var _imageClass:Class;
    public function get imageClass():Class {
      return this._imageClass;
    }

    public function set imageClass(imageClass:Class):void {
      this._imageClass = imageClass;
    }
</pre>
<p>Of course, this code won&#8217;t get us the image added to our display list, since we haven&#8217;t instantiated it yet. We could instantiate it and add it there, but of course, we wouldn&#8217;t know what size it should be, or whether we&#8217;ll have a border eventually or not. The addition and positioning of the image should take place within the implementation rules of UIComponent. So we&#8217;ll follow this order to draw any image:</p>
<ol>
<li><strong><code>commitProperties</code></strong>: Remove the old image if any, add the new one.
<li><strong><code>measure</code></strong>: Retrieve the size of the image, and use that, plus any border and padding of the parent, and set <code>measuredWidth</code> and <code>measuredHeight</code> to those values.
<li><strong><code>updateDisplayList</code></strong></li>
<p>: Position the image, offset by any padding and border, with the width governed by those values, plus the widths and heights of any scrollbars.
</ol>
<p>Clearly, changing the image will upset all of these, so we change our setter to the following to invalidate the properties, size, and rendering of our component:</p>
<pre>
    private var imageClassChanged:Boolean = true;
    protected var currentImage:DisplayObject;
    protected var _imageClass:Class; 

    public function get imageClass():Class {
      return this._imageClass;
    }

    public function set imageClass(imageClass:Class):void {
      this._imageClass = imageClass;
      this.imageClassChanged = true;
      this.invalidateProperties();
      this.invalidateSize();
      this.invalidateDisplayList();
    }
</pre>
<p>Having a flag variable (in this case, <code>imageClassChanged</code>) is a common practice amongst components. We use this flag in <code>commitProperties</code> so that we only update what&#8217;s been changed. We keep the image currently being rendered in a new variable named <code>currentImage</code>, with the imageClass being the cheap, inexpensive variable being changed  in the setter.</p>
<p>Now for UIComponent&#8217;s three methods we&#8217;re overriding. With the exception of <code>updateDisplayList</code>, these methods would look the same if you were implementing any kind of component, but I&#8217;ll cover them here for completeness:</p>
<p><strong><em>1. Implementing <code>commitProperties</code></em></strong></p>
<p>The code will look like this:</p>
<pre>
override protected function commitProperties():void {
  super.commitProperties();
  if(this.imageClassChanged) {
    this.imageClassChanged = false;
    if(this.currentImage) {
      // Clear our old image if any.
      this.removeChild(this.currentImage);
      this.currentImage = null;
    }
    if(this.imageClass) {
      // We have a new image, so load it up.
      this.currentImage = new this.imageClass();

      // Make it invisible for now until it's properly positioned.
      this.currentImage.visible = false;
      this.currentImage.mask = this.maskShape;

      // Finally, add it to our display list.
      this.addChild(this.currentImage);
    }
  }
}
</pre>
<p>This code doesn&#8217;t look very different from any other implementation of <code>commitProperties</code> so I won&#8217;t cover it in depth. Basically, you check your flag, and if its true, clear out the old image, and add your new one in. The critical pieces are here are the assignments to <code>mask</code>. Remember to clear the old one otherwise any reuse of the removed image will result in unpredictable behavior. Also, remember to set the new image&#8217;s mask to the <code>maskShape</code> property.</p>
<p>You should probably also set the new image&#8217;s <code>visible</code> property to false, otherwise you might end up with some unwanted flicker of the unpositioned image in its default size and position.</p>
<p><strong><em>2. Implementing <code>measure</code></em></strong></p>
<pre>
override protected function measure():void {
  super.measure();

  var edgeMetrics:EdgeMetrics = this.viewMetrics;

  var width:Number = edgeMetrics.left + edgeMetrics.right;
  var height:Number = edgeMetrics.top + edgeMetrics.bottom;

  if(this.currentImage) {
    // We have a real image, so get its dimensions.
    width += this.currentImage.width * this.currentImage.scaleX;
    height += this.currentImage.height * this.currentImage.scaleY;

  } else {
    // No image, so just set it to our edgeMetrics, with an added default size of 40x40
    var defaultSize:Number = 40;
    width += defaultSize;
    height += defaultSize;
  }
  this.measuredWidth = width;
  this.measuredHeight = height;
}
</pre>
<p>Nothing amazing here either. The complicated piece is getting the size of the image, and getting some default size otherwise. An important note here is the use of <code>viewMetrics</code>. That will give you the size of the border in the ScrollControlBase you&#8217;re using, along with any visible scrollbar sizes. Forgetting to use this could result in clipping of the scrollbars if your content is unusually small, so add them to your measured values.</p>
<p><strong><em>3. Implementing <code>updateDisplayList</code></em></strong></p>
<p>First, the code:</p>
<pre>
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
  super.updateDisplayList(unscaledWidth, unscaledHeight);

  if(!this.currentImage)
    return;

  var edgeMetrics:EdgeMetrics = this.viewMetrics;

  this.currentImage.x = edgeMetrics.left + -this.horizontalScrollPosition;
  this.currentImage.y = edgeMetrics.top + -this.verticalScrollPosition;

  // Make the image visible.
  this.currentImage.visible = true;
}
</pre>
<p>Again, using <code>viewMetrics</code> gets you the necessary offsets for your image. Since we&#8217;ve assigned <code>mask</code> of our currentImage already, there&#8217;s actually nothing ScrollControlBase-specific here at all.</p>
<p>Viewing the component in this state will show you a properly masked image if one&#8217;s assigned, surrounded by a inset border. Really, the implementation so far is quite simple, with the complexity coming from simply implementing a custom component; ScrollControlBase doesn&#8217;t get in the way at all, and provides its mask for easy use for your component.</p>
<p>Of course, a critical issue here is that while the image is properly masked, there&#8217;s no way to scroll with it. We&#8217;ll cover this issue in the <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-getting-scrolling-to-work/">next post on getting scrolling to work</a>.</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dafrito.wordpress.com/6/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dafrito.wordpress.com/6/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dafrito.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dafrito.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dafrito.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dafrito.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dafrito.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dafrito.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dafrito.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dafrito.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dafrito.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dafrito.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dafrito.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dafrito.wordpress.com/6/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dafrito.wordpress.com/6/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dafrito.wordpress.com/6/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=6&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-displaying-the-scrollbars/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/98e75f40b07fc2dddbc700e609bbcea2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dafrito</media:title>
		</media:content>
	</item>
		<item>
		<title>Extending ScrollControlBase: Its Internals and Design Philosophy</title>
		<link>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-its-internals-and-design-philosophy/</link>
		<comments>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-its-internals-and-design-philosophy/#comments</comments>
		<pubDate>Mon, 28 Apr 2008 07:24:51 +0000</pubDate>
		<dc:creator>Aaron Faanes</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[ScrollControlBase]]></category>
		<category><![CDATA[Component]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Scrolling]]></category>

		<guid isPermaLink="false">http://dafrito.wordpress.com/?p=5</guid>
		<description><![CDATA[This article is a 4-post series on extending ScrollControlBase. This post discusses how ScrollControlBase works internally, specifically how masks work, and what ScrollControlBase does, and doesn&#8217;t do, for subclasses. Here&#8217;s some links to the other posts in this article: 1. Its Internals and Design Philosophy 2. Displaying the Scrollbars 3. Getting Scrolling to Work 4. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=5&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This article is a 4-post series on extending ScrollControlBase. This post discusses how ScrollControlBase works internally, specifically how masks work, and what ScrollControlBase does, and doesn&#8217;t do, for subclasses.<span id="more-5"></span> Here&#8217;s some links to the other posts in this article:<br />
1. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-its-internals-and-design-philosophy/"> Its Internals and Design Philosophy</a><br />
2. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-displaying-the-scrollbars/"> Displaying the Scrollbars</a><br />
3. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-getting-scrolling-to-work/"> Getting Scrolling to Work</a><br />
4. <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-the-workflow/">The Workflow</a></p>
<p>ScrollControlBase is one of those mystery classes that does a shitton of actual work, but isn&#8217;t mentioned much at all in the API documentation (<a href="http://livedocs.adobe.com/flex/2/langref/mx/core/ScrollControlBase.html">Aside from the ScrollControlBase Reference, of course</a>). That&#8217;s probably because it&#8217;s not intended to be used directly, but rather subclassed (Like ListBase, TileBase, and all the other Bases)</p>
<p>The problem is that I need to extend ScrollControlBase to implement a special kind of behavior: Vertically aligned content so that it appears from the bottom up, like in IRC clients, and some chat windows. I managed to do it with regular text by extending TextArea, but now I need to do it with an HTML element, and extending HTML didn&#8217;t work for me, so I decided to extend ScrollControlBase to build the functionality in directly. While I was at it, I wrote up what ScrollControlBase actually does for you, and the workflow needed to extend ScrollControlBase properly:</p>
<p><strong>The Design of ScrollControlBase</strong></p>
<p>ScrollControlBase is not a container, as it is intended to be subclassed. This has a few implications: Firstly, ScrollControlBase does not work via composition; it does not take some <code>.content</code> parameter that&#8217;s your content and magically positions it. Rather, it does no drawing of your content at all. It draws the scrollbars, any provided border, and exposes an interface to set their position. It displays the scrolled content accurately via a <a href="http://en.wikipedia.org/wiki/Mask_%28computing%29#Image_masks">mask</a>.</p>
<p><strong>Understanding Masks</strong></p>
<p>What a mask does is fairly simple. For the visual people, imagine a piece of paper, with the center cut out. Placing that paper on top of some image, or some article &#8220;masks&#8221; the rest of the image, showing only a portion. Now, for computers, this mask isn&#8217;t the paper, but the shape of the cutout. So if you cut out a circle, the mask you&#8217;d use would be a rendered circle. Every display object in flash has a <code>mask</code> property that accepts any display object, and those two are used together to render some image.</p>
<p>If you&#8217;re interested in how masks work at a technical level, read on. Otherwise, just skip this section:</p>
<p>For those more mathematically oriented, imagine two values in binary. The first value is 11110000, or four ones followed by four zeros. The second is 00111100, or four ones, with four zeros evenly divded on either side. Apply the bitwise &amp; operation (which returns the value where both values are true in that location, 1 &amp; 1 is 1,  0 &amp; 0 is 0, along with 1 &amp; 0, and 0 &amp; 1). The bitwise &amp; applied to our two values returns 00110000. At a bitwise level, a mask is just using &amp; creatively, and neither value is inherently a mask or not.</p>
<p>At a higher level, the mask is usually itself some primitive image. Typically, all of a mask&#8217;s values are used to produce the derivation. That is, a black image masked over some source image, would produce an image the shape of the mask, with the image coming from the source. That&#8217;s of course not to say that some specific color channel couldn&#8217;t be used as the mask, producing the images showing only the reds, greens, or blues in some image.</p>
<p>For further information, check out <a href="http://www.insideria.com/2008/01/flex-graphics-tricks-part-1-ma.html">this post on masks specifically in Flash and their various uses</a></p>
<p><strong>What ScrollControlBase doesn&#8217;t do</strong></p>
<p>ScrollControlBase, as previously mentioned, only draws a mask over its children, and adds interface to support scroll bars, positions, and adding a border. It doesn&#8217;t manipulate the position, or size, of the content it contains.</p>
<p>That ScrollControlBase has no default scrolling behavior could be construed as a weakness, since ScrollControlBase could directly manage the position of its content, and not have to have subclasses do it. However, that would mean that the subclasses would have to have their content fully rendered*. For very long lists, this would be very expensive to do. Instead, it lets children build in their own optimizations, like in the case of ListBase, which recycles its renders; as you scrol through the list, fully occluded renders are added to a freed list, and used to display the content coming up from the bottom. This allows list implementations to be as inexpensive as possible, since everything is done just in time.</p>
<p>*One could argue that the list being rendered could just give a filler for the content not exposed, allowing ScrollControlBase to still function as normal. This would work, but you&#8217;re still having to recycle renderers to gain the same level of functionality, so you&#8217;re not saving yourselves much as far as work needed to do to draw your list. I&#8217;d assume Flex developers figured each implementation would differ greatly enough in its optimziation that providing a default way would be too ambiguous to be useful.</p>
<p>Read on to see <a href="http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-displaying-the-scrollbars/">how to actually implement a sublcass of ScrollControlBase.</a></p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dafrito.wordpress.com/5/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dafrito.wordpress.com/5/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dafrito.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dafrito.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dafrito.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dafrito.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dafrito.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dafrito.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dafrito.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dafrito.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dafrito.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dafrito.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dafrito.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dafrito.wordpress.com/5/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dafrito.wordpress.com/5/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dafrito.wordpress.com/5/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dafrito.wordpress.com&amp;blog=3584532&amp;post=5&amp;subd=dafrito&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dafrito.wordpress.com/2008/04/28/extending-scrollcontrolbase-its-internals-and-design-philosophy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/98e75f40b07fc2dddbc700e609bbcea2?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dafrito</media:title>
		</media:content>
	</item>
	</channel>
</rss>
