<?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/"
	>

<channel>
	<title>REPPA.NET</title>
	<atom:link href="http://blog.reppa.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.reppa.net</link>
	<description>dev blog</description>
	<lastBuildDate>Wed, 30 Nov 2011 18:11:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>iOS: Skinning der UISegmentedControl-Komponente</title>
		<link>http://blog.reppa.net/2011/11/ios-skinning-der-uisegmentcontrol-komponente/</link>
		<comments>http://blog.reppa.net/2011/11/ios-skinning-der-uisegmentcontrol-komponente/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 18:35:36 +0000</pubDate>
		<dc:creator>Daniel Schmidt</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[backgroundImage]]></category>
		<category><![CDATA[dividerImage]]></category>
		<category><![CDATA[iOS 5]]></category>
		<category><![CDATA[titleTextAttributes]]></category>
		<category><![CDATA[UISegmentedControl]]></category>

		<guid isPermaLink="false">http://blog.reppa.net/?p=231</guid>
		<description><![CDATA[Dieser Blogeintrag befasst sich mit dem Skinning der UISegmentedControl-Komponente, was sich mit iOS 5 nun einfacher gestaltet. So sieht die Komponente in ihren normalen Zustand aus: Seit iOS 5 werden die Methoden setBackgroundImage: forState: barMetrics: und setDividerImage: forLeftSegmentState: rightSegmentState: barMetrics: &#8230; <a href="http://blog.reppa.net/2011/11/ios-skinning-der-uisegmentcontrol-komponente/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Dieser Blogeintrag befasst sich mit dem Skinning der UISegmentedControl-Komponente, was sich mit iOS 5 nun einfacher gestaltet. So sieht die Komponente in ihren normalen Zustand aus:</p>
<p><img src="http://blog.reppa.net/wp-content/uploads/2011/11/uisegmentedcontrol_normal.png" alt="default look" width="306" height="54" class="aligncenter size-full wp-image-233" /></a><br />
Seit iOS 5 werden die Methoden <strong>setBackgroundImage: forState: barMetrics:</strong> und <strong>setDividerImage: forLeftSegmentState: rightSegmentState: barMetrics:</strong> bereitgestellt, mit denen das Aussehen der Komponente im Handumdrehen verändert werden kann.</p>
<p><img src="http://blog.reppa.net/wp-content/uploads/2011/11/uisegmentedcontrol_skinned.png" alt="skinned UISegmentedControl" width="295" height="53" class="aligncenter size-full wp-image-234" /></a><br />
Der verwendete Code für die obrige Darstellung sieht folgendermaßen aus:</p>
<pre class="brush: objc;">
    // navigation is an UISegmentedControl
    // BACKGROUND
    // unselected
    UIImage *unselected = [[UIImage imageNamed:@&quot;unselected.png&quot;]
                           resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
    [[self navigation] setBackgroundImage:unselected
                                           forState:UIControlStateNormal
                                         barMetrics:UIBarMetricsDefault];

    // selected
    UIImage *selected = [[UIImage imageNamed:@&quot;selected.png&quot;]
                         resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
    [[self navigation] setBackgroundImage:selected
                                           forState:UIControlStateSelected
                                         barMetrics:UIBarMetricsDefault];

    // DIVIDER
    // unselected/unselected
    UIImage *unselectedUnselected = [UIImage imageNamed:@&quot;unselected_unselected.png&quot;];
    [[self navigation] setDividerImage:unselectedUnselected
                             forLeftSegmentState:UIControlStateNormal
                               rightSegmentState:UIControlStateNormal
                                      barMetrics:UIBarMetricsDefault];

    // selected/unselected
    UIImage *selectedUnselected = [UIImage imageNamed:@&quot;selected_unselected.png&quot;];
    [[self navigation] setDividerImage:selectedUnselected
                             forLeftSegmentState:UIControlStateSelected
                               rightSegmentState:UIControlStateNormal
                                      barMetrics:UIBarMetricsDefault];

    // unselected/selected
    UIImage *unselectedSelected = [UIImage imageNamed:@&quot;unselected_selected.png&quot;];
    [[self navigation] setDividerImage:unselectedSelected
                             forLeftSegmentState:UIControlStateNormal
                               rightSegmentState:UIControlStateSelected
                                      barMetrics:UIBarMetricsDefault];
</pre>
<p>Die Eigenschaften des Labels können mit der Methode <strong>setTitleTextAttributes: forState:</strong> verändert werden.</p>
<pre class="brush: objc;">
   // navigation is an UISegmentedControl
   // STATE NORMAL
    [navigation setTitleTextAttributes:
     [NSDictionary dictionaryWithObjectsAndKeys:
      [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0],
      UITextAttributeTextColor,
      [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
      UITextAttributeTextShadowColor,
      [NSValue valueWithUIOffset:UIOffsetMake(0, -1)],
      UITextAttributeTextShadowOffset,
      nil] forState:UIControlStateNormal];

    // STATE SELECTED
    [navigation setTitleTextAttributes:
     [NSDictionary dictionaryWithObjectsAndKeys:
      [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0],
      UITextAttributeTextColor,
      [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8],
      UITextAttributeTextShadowColor,
      [NSValue valueWithUIOffset:UIOffsetMake(0, -1)],
      UITextAttributeTextShadowOffset,
      nil] forState:UIControlStateSelected];
</pre>
<p>Das hier verwendete Beispiel verändert die Farbe der Labels für den normalen und selektierten Zustand.</p>
<p><img src="http://blog.reppa.net/wp-content/uploads/2011/11/uisegmentedcontrol_text.png" alt="skinned UISegmentedControl" width="296" height="55" class="aligncenter size-full wp-image-236" /></a><br />
Die verwendeten Grafiken für die Segmente selber sind nicht auf die Buttonform beschränkt. Hier ein Beispiel, in dem die Segmente eher an Tabs erinnern:</p>
<p><img src="http://blog.reppa.net/wp-content/uploads/2011/11/uisegmentedcontrol_tab.png" alt="skinned UISegmentedControl" width="338" height="90" class="aligncenter size-full wp-image-237" /></a></p>
<p>Das komplette Beispiel mit allen Grafiken und dem Code könnte ihr <a href="http://blog.reppa.net/wp-content/uploads/2011/11/SkinnedUISegmentedCotrol.zip">hier als Xcode-Projekt</a> herunterladen.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reppa.net/2011/11/ios-skinning-der-uisegmentcontrol-komponente/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ItemRenderer: ab-/anmelden von EventListenern</title>
		<link>http://blog.reppa.net/2011/10/itemrenderer-eventlistener/</link>
		<comments>http://blog.reppa.net/2011/10/itemrenderer-eventlistener/#comments</comments>
		<pubDate>Mon, 31 Oct 2011 20:20:03 +0000</pubDate>
		<dc:creator>Daniel Schmidt</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[EventListener]]></category>
		<category><![CDATA[GarbageCollection]]></category>
		<category><![CDATA[ItemRenderer]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.reppa.net/?p=219</guid>
		<description><![CDATA[Viele Beispiele im Netz zeigen, wie schnell und einfach sich ItemRenderer für Flex-Komponenten erstellen lassen. Leider sind diese Beispiele für größere Anwendungen kaum zu gebrauchen, da entweder die Performance durch die vielen Bindings verloren geht, oder verwendete EventListener nicht mehr &#8230; <a href="http://blog.reppa.net/2011/10/itemrenderer-eventlistener/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Viele Beispiele im Netz zeigen, wie schnell und einfach sich ItemRenderer für Flex-Komponenten erstellen lassen. Leider sind diese Beispiele für größere Anwendungen kaum zu gebrauchen, da entweder die Performance durch die vielen Bindings verloren geht, oder verwendete EventListener nicht mehr abgemeldet werden.</p>
<p>Aber wann ist nun der richtige Zeitpunkt um EventListener in ItemRenderern wieder abzumelden? Da die meisten Flex-Komponenten die Renderer intern wiederverwenden (es wird lediglich die data-Eigenschaft des Renderers geändert), besteht die Möglichkeit bei Änderungen dieser Eigenschaft die Listener abzumelden.</p>
<pre class="brush: as3;">
private var _dataChanged:Boolean;

    /**
     * @inheritDoc
     */
    override public function set data(value:Object):void {
        if (data != value) {
            if (data) {
                removeDataListener();
            }
            super.data = value;
            _dataChanged = true;
            invalidateProperties();
        }
    }

    /**
     * @inheritDoc
     */
    override protected function commitProperties():void {
        super.commitProperties();

        if (_dataChanged) {
            _dataChanged = false;
            if (data) {
                addDataListener();
                // do other stuff here
            }
        }
    }

    protected function removeDataListener():void {
        // remove data listener
    }

    protected function addDataListener():void {
        // add data listener
    }
</pre>
<p>Leider ist dies nur die halbe Miete. Was passiert wenn die Flex-Komponente, die die Renderer verwendet, oder der Renderer selbst aus der DisplayList entfernt wird? Es existieren immer noch die Listener innerhalb des Renderers, der dadurch vor der <a href="http://www.adobe.com/devnet/actionscript/learning/oop-concepts/garbage-collection.html">GarbageCollection</a> (GC) geschützt wird. Dies betrifft nur Listener die nicht als weak-Listener angemeldet wurden.</p>
<p>Aus diesem Grund melden wir uns für das  Event <a href="http://help.adobe.com/de_DE/FlashPlatform/reference/actionscript/3/flash/events/Event.html#REMOVED_FROM_STAGE">&#8220;REMOVED_FROM_STAGE&#8221;</a> an und sorgen dafür, dass alle Listener abgemeldet werden. Lediglich der Listener für das Event &#8220;REMOVED_FROM_STAGE&#8221; bleibt bestehen, da es vorkommen kann, dass eine Flex-Komponente ihre Renderer aus der DisplayList nimmt und später wiederverwendet. Der Renderer wird trotz des &#8220;REMOVED_FROM_STAGE&#8221;-Listeners von der GC entfernt,  da dieser als weak-Listener angemeldet wurde.</p>
<pre class="brush: as3;">
package {

import flash.events.Event;
import mx.core.EventPriority;
import spark.components.supportClasses.ItemRenderer;

public class BaseItemRenderer extends ItemRenderer {

    private var _dataChanged:Boolean;

    /**
     * Constructor.
     */
    public function BaseItemRenderer() {
        addEventListener(Event.REMOVED_FROM_STAGE, onRemovedFromStage, false, EventPriority.DEFAULT, true);
    }

    /**
     * @inheritDoc
     */
    override public function set data(value:Object):void {
        if (data != value) {
            if (data) {
                removeDataListener();
            }
            super.data = value;
            _dataChanged = true;
            invalidateProperties();
        }
    }

    /**
     * @inheritDoc
     */
    override protected function commitProperties():void {
        super.commitProperties();

        if (_dataChanged) {
            _dataChanged = false;
            if (data) {
                addDataListener();
                // do other stuff here
            }
        }
    }

    // Should be used to free all unused data.
    protected function dispose():void {
        data = null;
        // do other stuff here
    }

    protected function removeDataListener():void {
        // remove data listener
    }

    protected function addDataListener():void {
        // add data listener
    }

    private function onRemovedFromStage(event:Event):void {
        dispose();
    }
}
}
</pre>
<p>Die endgültige Version des hier vorgestellten ItemRenderers könnt ihr <a href="http://blog.reppa.net/wp-content/uploads/2011/11/BaseItemRenderer.as_.zip">hier herunterladen</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reppa.net/2011/10/itemrenderer-eventlistener/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PureMVC: EventMapMediator &#8211; automatisiertes Entfernen aller Eventlistener</title>
		<link>http://blog.reppa.net/2011/09/puremvc-eventmapmediator-automatisiertes-entfernen-aller-eventlistener/</link>
		<comments>http://blog.reppa.net/2011/09/puremvc-eventmapmediator-automatisiertes-entfernen-aller-eventlistener/#comments</comments>
		<pubDate>Sun, 25 Sep 2011 17:20:16 +0000</pubDate>
		<dc:creator>Daniel Schmidt</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Event]]></category>
		<category><![CDATA[Mediator]]></category>
		<category><![CDATA[PureMVC]]></category>

		<guid isPermaLink="false">http://blog.reppa.net/?p=209</guid>
		<description><![CDATA[Jeder Mediator im PureMVC Framework, der sich bei seiner Viewkomponente für Events anmeldet muss diese spätestens beim entfernen des Mediators auch wieder abmelden. In der Regel sieht der Code im Mediator, für das An- und Abmelden, folgendermaßen aus: public class &#8230; <a href="http://blog.reppa.net/2011/09/puremvc-eventmapmediator-automatisiertes-entfernen-aller-eventlistener/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Jeder Mediator im <a href="http://puremvc.org/">PureMVC Framework</a>, der sich bei seiner Viewkomponente für Events anmeldet muss diese spätestens beim entfernen des Mediators auch wieder abmelden.<br />
In der Regel sieht der Code im Mediator, für das An- und Abmelden, folgendermaßen aus:</p>
<pre class="brush: as3;">
public class LoginMediator extends Mediator
{
	override public function onRegister():void {
		view.addEventListener(Event.A, eventAHandler);
		view.addEventListener(Event.B, eventBHandler);
		...
		view.addEventListener(Event.Z, eventZHandler);
	}

	override public function onRemove():void {
		view.removeEventListener(Event.A, eventAHandler);
		view.removeEventListener(Event.B, eventBHandler);
		...
		view.removeEventListener(Event.Z, eventZHandler);
	}

	private function get view():DisplayObject{
		return DisplayObject(viewComponent);
	}
}
</pre>
<p>Dabei muss der Entwickler selbst darauf achten, dass er auch wirklich alle Eventlistener wieder abmeldet.<br />
Das Framework <a href="http://www.robotlegs.org/">Robotlegs</a> bietet für diesen Fall einen automtisierten Ansatz, dort werden selbstständig alle registrierten Eventlistener abgemeldet sobald ein Mediator entfernt wird. Diese Funktionalität habe ich für das PureMVC Framework adaptiert und eine neue Mediatorklasse erstellt.<br />
Alle Eventlistener die über die Methode &#8220;addViewListener&#8221; registriert werden, werden automatisch beim entfernen des Mediators Abgemeldet.<br />
Sodass das vorherige Beispiel nun so aussieht:</p>
<pre class="brush: as3;">
public class LoginMediator extends EventMapMediator
{
	override public function onRegister():void {
		addViewListener(Event.A, eventAHandler);
		addViewListener(Event.B, eventBHandler);
		...
		addViewListener(Event.Z, eventZHandler);
	}

	private function get view():DisplayObject{
		return DisplayObject(viewComponent);
	}
}
</pre>
<p>Die EventMap selber ist nicht vom Mediator abhängig und kann somit auch in Viewkomponenten verwendet werden. Dort muss sich aber selber darum gekümmert werden, die Eventlistener auch wieder zu entfernen, um Memoryleaks zu vermeiden.</p>
<p>Die Klassen findet ihr <a href="http://blog.reppa.net/wp-content/uploads/2011/09/EventMapMediator.zip">hier als Zip-Datei</a> zum Download.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reppa.net/2011/09/puremvc-eventmapmediator-automatisiertes-entfernen-aller-eventlistener/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flex: Tree-Komponente mit unterschiedlichen ItemRenderern</title>
		<link>http://blog.reppa.net/2011/08/flex-tree-komponente-mit-verschiedenen-itemrenderer/</link>
		<comments>http://blog.reppa.net/2011/08/flex-tree-komponente-mit-verschiedenen-itemrenderer/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 20:08:28 +0000</pubDate>
		<dc:creator>Daniel Schmidt</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[ItemRenderer]]></category>
		<category><![CDATA[Tree]]></category>

		<guid isPermaLink="false">http://blog.reppa.net/?p=194</guid>
		<description><![CDATA[Da die Tree-Komponente nur eine Instanz eines ItemRenderers intern zur Darstellung der Daten verwendet, muss dieser Renderer das Aussehen aller Baumelemente beinhalten. Dies kann dazu führen, dass der ItemRenderer sehr viel Code enthält, wenn für Verzweigungen und Blätter des Trees &#8230; <a href="http://blog.reppa.net/2011/08/flex-tree-komponente-mit-verschiedenen-itemrenderer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Da die Tree-Komponente nur eine Instanz eines ItemRenderers intern zur Darstellung der Daten verwendet, muss dieser Renderer das Aussehen aller Baumelemente beinhalten. Dies kann dazu führen, dass der ItemRenderer sehr viel Code enthält, wenn für Verzweigungen und Blätter des Trees verschiedene Funktionalitäten und Aussehen gewünscht sind. Um dies zu vermeiden, habe ich die Tree-Komponente so erweitert, dass für jedes Baumelement ein anderer ItemRenderer verwendet werden kann.</p>
<pre class="brush: as3;">
package {
import mx.controls.Tree;
import mx.core.IFactory;

/**
 * Adds support for multiple itemRenderer.
 * The default implementation of the tree supports only one type of renderer for all items.
 */
public class ExtendedTree extends Tree {

    /**
     * This method is used to retrieve a factory which creates an itemRenderer for an object.
     * The signature of the function should look like: &quot;myCustomFunction(data:Object):IFactory&quot;
     */
    public var resolveItemRendererFunction:Function;

    /**
     * @inheritDoc
     */
    override public function getItemRendererFactory(data:Object):IFactory {
        if (resolveItemRendererFunction != null) {
            return resolveItemRendererFunction(data);
        } else {
            return super.getItemRendererFactory(data);
        }
    }
}
}
</pre>
<p>Hier sieht man den Unterschied zwischen der erweiterte Komponente (links), welche zwei verschiedene ItemRenderer verwendet, und der normalen Tree-Komponente (rechts):</p>
<p style="text-align: center"><img src="http://blog.reppa.net/wp-content/uploads/2011/08/flex_tree_component.png" alt="Tree-Komponente" /></p>
<p>Das Beispiel aus den Screenshoots kann <a href="http://blog.reppa.net/wp-content/uploads/2011/08/Tree-example.zip">hier heruntergeladen</a> werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reppa.net/2011/08/flex-tree-komponente-mit-verschiedenen-itemrenderer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>iOS-Entwicklung: BAD_ACCESS-Fehler mit NSZombieEnabled Debuggen</title>
		<link>http://blog.reppa.net/2011/07/bad_access-mit-nszombieenabled-debuggen/</link>
		<comments>http://blog.reppa.net/2011/07/bad_access-mit-nszombieenabled-debuggen/#comments</comments>
		<pubDate>Sun, 31 Jul 2011 13:17:31 +0000</pubDate>
		<dc:creator>Daniel Schmidt</dc:creator>
				<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[BAD_ACCESS]]></category>
		<category><![CDATA[NSZombieEnabled]]></category>
		<category><![CDATA[releaseCount]]></category>
		<category><![CDATA[Xcode]]></category>

		<guid isPermaLink="false">http://blog.reppa.net/?p=184</guid>
		<description><![CDATA[Jeder der schon einmal einen BAD_ACCESS-Fehler in einer Anwendung beheben musste, weiß wie umständlich dies sein kann. Da diese Art von Fehler an irgendeiner Stelle im Programm auftritt, und keinen Rückschluss auf den Code gibt der diesen Fehler verursacht hat. &#8230; <a href="http://blog.reppa.net/2011/07/bad_access-mit-nszombieenabled-debuggen/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Jeder der schon einmal einen <strong>BAD_ACCESS</strong>-Fehler in einer Anwendung beheben musste, weiß wie umständlich dies sein kann. Da diese Art von Fehler an irgendeiner Stelle im Programm auftritt, und keinen Rückschluss auf den Code gibt der diesen Fehler verursacht hat.<br />
Glücklicherweise gibt es aber die Umgebungsvariable <strong>NSZombieEnabled</strong>, die dafür sorgt das Objekte deren <em>releaseCount</em> gleich 0 ist nicht gelöscht werden. Wird im Laufe des Programms eine Nachricht an ein solches Objekt gesendet, bleibt der Debugger sofort stehen. Dadurch kann genau analysiert werden, an welcher Stelle im Code der fehlerhafte Zugriff erfolgte.</p>
<p>Erstellen der Variable (Xcode 4.1):<br />
Mit gedrückter <em>alt-Taste</em> auf den <em>Run-Button</em> klicken.<br />
Durch die gedrückte Taste öffnet sich ein Fenster in dem diverse Einstellungen vorgenommen werden können. Im Fenster auf den Reiter <em>&#8220;Arguments&#8221;</em> gehen und unter <em>&#8220;Environment Variables&#8221;</em> eine neue Variable mit dem Namen <em>NSZombieEnabled</em> erstellen und ihr den Wert <em>YES</em> zuweisen.</p>
<p>Nach dem Debuggen sollte diese Variable wieder entfernt oder zumindest auf <em>FALSE</em> gesetzt werden, da ansonsten Memoryleaks entstehen!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reppa.net/2011/07/bad_access-mit-nszombieenabled-debuggen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flaschenhals: Binding</title>
		<link>http://blog.reppa.net/2011/06/flaschenhals-binding/</link>
		<comments>http://blog.reppa.net/2011/06/flaschenhals-binding/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 18:58:00 +0000</pubDate>
		<dc:creator>Daniel Schmidt</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[bindable]]></category>
		<category><![CDATA[binding]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.reppa.net/?p=177</guid>
		<description><![CDATA[Ein sehr mächtiges Feature in Flex ist das [Bindable]-Metadata-Tag. Man sollte sich aber dennoch bewusst sein, dass auch das Binding einige Nachteile mit sich bringen kann. Wenn eine Klasse oder Properties einer Klasse mithilfe des [Bindable]-Tags für den Compiler markiert &#8230; <a href="http://blog.reppa.net/2011/06/flaschenhals-binding/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Ein sehr mächtiges Feature in Flex ist das [Bindable]-Metadata-Tag.  Man sollte sich aber dennoch bewusst sein, dass auch das Binding einige Nachteile mit sich bringen kann. Wenn eine Klasse oder Properties einer Klasse mithilfe des [Bindable]-Tags für den Compiler markiert werden, generiert dieser aus der Property einen Getter und Setter. Im Setter wird dann ein PropertyChangeEvent versendet. Damit ein anderes Objekt über die Änderung informiert werden kann, wird diese vom Compiler als Empfänger für das PropertyChangeEvent angemeldet.</p>
<p>Da jede so markierte Property ein PropertyChangeEvent versendet, wird zusätzlich geprüft, welche Property geändert wurde. Wird ein Objekt nun an eine Property einer komplexen Klasse (viele [Bindable]-markierte Properties) gebunden, führt dies zu spürbaren Performanceeinbußen.</p>
<p>Dem kann jedoch Abhilfe geschaffen werden, indem im [Bindable]-Tag zusätzlich noch das Event definiert wird (z.B. [Bindable (event="xyChanged")]), welches bei einer Änderung der Property versendet wird. Leider generiert der Compiler nicht die entsprechende Benachrichtigung, so dass der Programmierer selber dafür sorgen muss, das Event zu versenden.</p>
<pre class="brush: as3;">
package
{
    import flash.events.EventDispatcher;
    import flash.events.Event;

    public class ExampleVO extends EventDispatcher
    {
        private var _description:String;

        [Bindable(event=&quot;descriptionChanged&quot;)]
        public function get description():String {
            return _description;
        }

        public function set description(value:String):void {
            if (_description !== value) {
                _description = value;
                if (hasEventListener(&quot;descriptionChanged&quot;)) {
                    dispatchEvent(new Event(&quot;descriptionChanged&quot;));
                }
            }
        }
    }
}
</pre>
<p>Dies erfordert einige Zeilen mehr Code. In komplexen Anwendungen kann dadurch einiges an Performance gewonnen werden, da nun das ermitteln der geänderten Property entfällt.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reppa.net/2011/06/flaschenhals-binding/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vector als &#8220;dataProvider&#8221; für Flex-View-Komponenten</title>
		<link>http://blog.reppa.net/2011/05/vector-als-dataprovider-fur-flex-viewkomponenten/</link>
		<comments>http://blog.reppa.net/2011/05/vector-als-dataprovider-fur-flex-viewkomponenten/#comments</comments>
		<pubDate>Fri, 27 May 2011 12:38:39 +0000</pubDate>
		<dc:creator>Daniel Schmidt</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[dataProvider]]></category>
		<category><![CDATA[Vector]]></category>
		<category><![CDATA[VectorCollection]]></category>
		<category><![CDATA[VectorList]]></category>

		<guid isPermaLink="false">http://blog.reppa.net/?p=152</guid>
		<description><![CDATA[Seit der Einführung des FlashPlayers 10, steht dem Entwickler die Klasse Vector zur Verfügung. Diese bringt gegenüber dem Array einige Vorteile mit sich, doch spätestens bei der Zuweisung eines Vectors als &#8220;dataProvider&#8221; für View-Komponenten steht der Entwickler vor einem Problem. &#8230; <a href="http://blog.reppa.net/2011/05/vector-als-dataprovider-fur-flex-viewkomponenten/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Seit der Einführung des FlashPlayers 10, steht dem Entwickler die Klasse Vector zur Verfügung. Diese bringt gegenüber dem Array einige Vorteile mit sich, doch spätestens bei der Zuweisung eines Vectors als &#8220;dataProvider&#8221; für View-Komponenten steht der Entwickler vor einem Problem. Für die Array-Klasse existieren die Klassen ArrayList und ArrayCollection, die das Interface implementieren welches ein &#8220;dataProvider&#8221; benötigt. Wohingegen für die Klasse Vector keine Alternativen geboten werden.<br />
Da ich mir selber mehr als einmal diese Möglichkeit gewünscht hätte, habe ich analog zum Array die Klassen VectorList und VectorCollection erstellt. Mit Hilfe dieser Wrapperklassen kann nun auch ein Vector als &#8220;dataProvider&#8221; verwendet werden.</p>
<pre class="brush: as3;">
&lt;fx:Script&gt;
	&lt;![CDATA[
			import net.reppa.utils.collections.VectorCollection;
			import net.reppa.utils.collections.VectorList;

			private function initializeComboBox(vector:Vector.&lt;int&gt;):void{
				comboBox.dataProvider = new VectorCollection(vector);
				// or
				//comboBox.dataProvider = new VectorList(vector);
			}
	]]&gt;
&lt;/fx:Script&gt;

&lt;s:ComboBox id=&quot;comboBox&quot; /&gt;
</pre>
<p>Die Klassen findet ihr <a href='http://blog.reppa.net/wp-content/uploads/2011/05/dataProvider-support-for-Vector.zip'>hier</a> als Zip-Datei zum Download.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reppa.net/2011/05/vector-als-dataprovider-fur-flex-viewkomponenten/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Übergabe und Verarbeitung von eigenen Flex-Compiler-Argumenten (Compile-Time)</title>
		<link>http://blog.reppa.net/2011/05/ubergabe-und-verarbeitung-von-eigenen-flex-compiler-argumenten-compile-time/</link>
		<comments>http://blog.reppa.net/2011/05/ubergabe-und-verarbeitung-von-eigenen-flex-compiler-argumenten-compile-time/#comments</comments>
		<pubDate>Tue, 10 May 2011 15:33:13 +0000</pubDate>
		<dc:creator>Andy</dc:creator>
				<category><![CDATA[Flex]]></category>
		<category><![CDATA[ANT]]></category>
		<category><![CDATA[Buildscript]]></category>
		<category><![CDATA[Compiletime]]></category>

		<guid isPermaLink="false">http://blog.reppa.net/?p=130</guid>
		<description><![CDATA[Dieser Eintrag ergänzt die Übergabe und Verarbeitung von eigenen Flex-Compiler-Argumenten um ein ANT-Buildscript für Flex4, bei dem die Compile-Time als Compilerargument übergeben wird. Im ANT-Buildscript wird zuerst die aktuelle Zeit an eine ANT-Property &#8220;compiletime&#8221; übergeben: &#60;tstamp&#62; &#60;format property=&#34;compiletime&#34; pattern=&#34;dd.MM.yyyy, HH:mm:ss&#34; &#8230; <a href="http://blog.reppa.net/2011/05/ubergabe-und-verarbeitung-von-eigenen-flex-compiler-argumenten-compile-time/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Dieser Eintrag ergänzt die <a title="Übergabe und Verarbeitung von eigenen Flex-Compiler-Argumenten" href="http://blog.reppa.net/2010/11/ubergabe-und-verarbeitung-von-eigenen-flex-compiler-argumenten/" target="_self">Übergabe und Verarbeitung von eigenen Flex-Compiler-Argumenten</a> um ein ANT-Buildscript für Flex4, bei dem die Compile-Time als Compilerargument übergeben wird.</p>
<p>Im ANT-Buildscript wird zuerst die aktuelle Zeit an eine ANT-Property &#8220;compiletime&#8221; übergeben:</p>
<pre class="brush: xml;">
	&lt;tstamp&gt;
		&lt;format property=&quot;compiletime&quot; pattern=&quot;dd.MM.yyyy, HH:mm:ss&quot; /&gt;
	&lt;/tstamp&gt;
</pre>
<p>Diese Property wird dann im mxml-Task per &#8220;define&#8221; als Compilerargument hinzugefügt:</p>
<pre class="brush: xml;">
	  &lt;mxmlc file=&quot;${SRC_DIR}/Main.mxml&quot; output=&quot;${DEPLOY_DIR}/Main.swf&quot;&gt;
	  	&lt;define name=&quot;CONFIG::COMPILE_TIME&quot; value=&quot;'${compiletime}'&quot;/&gt;
	  	&lt;load-config filename=&quot;${FLEX_HOME}/frameworks/flex-config.xml&quot;/&gt;
		&lt;source-path path-element=&quot;${FLEX_HOME}/frameworks&quot;/&gt;
	  	&lt;compiler.debug&gt;false&lt;/compiler.debug&gt;
	  &lt;/mxmlc&gt;
</pre>
<p>Der Quellcode zu diesem Beispiel kann <a href="http://blog.reppa.net/wp-content/uploads/2011/05/ANT-Compile-Time.zip" target="_blank">hier</a> heruntergeladen werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reppa.net/2011/05/ubergabe-und-verarbeitung-von-eigenen-flex-compiler-argumenten-compile-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ItemRenderer, BindingUtils und Garbage Collection</title>
		<link>http://blog.reppa.net/2011/04/itemrenderer-bindingutils-und-garbage-collection/</link>
		<comments>http://blog.reppa.net/2011/04/itemrenderer-bindingutils-und-garbage-collection/#comments</comments>
		<pubDate>Thu, 28 Apr 2011 21:15:49 +0000</pubDate>
		<dc:creator>Daniel Schmidt</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[binding]]></category>
		<category><![CDATA[BindingUtils]]></category>
		<category><![CDATA[ChangeWatcher]]></category>

		<guid isPermaLink="false">http://blog.reppa.net/?p=117</guid>
		<description><![CDATA[Mit Hilfe der BindingUtils-Klasse kann man sich bei Objekten registrieren um über Änderungen einer bestimmten Property informiert zu werden. Dieser Mechanismus wird häufig in ItemRenderern verwendet. Leider enthält die API-Referenz zur BindingUtils-Klasse keinerlei Hinweise wie ein solches Binding wieder aufgelöst &#8230; <a href="http://blog.reppa.net/2011/04/itemrenderer-bindingutils-und-garbage-collection/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Mit Hilfe der BindingUtils-Klasse kann man sich bei Objekten registrieren um über Änderungen einer bestimmten Property informiert zu werden. Dieser Mechanismus wird häufig in ItemRenderern verwendet. Leider enthält die API-Referenz zur BindingUtils-Klasse keinerlei Hinweise wie ein solches Binding wieder aufgelöst werden kann. Ein nicht gelöschtes Binding wird im Speicher gehalten und ausgeführt auch wenn der ItemRenderer nicht mehr über Änderungen informiert werden will.</p>
<pre class="brush: as3;">
override public function set data(value:Object):void
{
	if (value != data)
	{
		super.data = value;
		BindingUtils.bindSetter( onPropertyChanged, value, &quot;property&quot; );
	}
}
</pre>
<p>ItemRenderer werden innerhalb von Komponenten wiederverwendet, d.h. ein ItemRenderer bekommt während seiner Lebenszeit verschiedene Datenobjekte zur Darstellung übergeben. Da wir im oben gezeigtem Code das Binding für die vorherigen Daten nicht entfernen wenn ein neues Datenobjekt gesetzt wird, würde der ItemRenderer auch Änderungen vom alten Datenobjekt mitbekommen. Was dazu führen kann das falsche Informationen angezeigt werden, nämlich dann wenn Properties des alten Datenobjektes verändert werden. Oder das die mit dem Binding verknüpfte Methode &#8220;onPropertyChanged&#8221; mehrfach aufgerufen wird wenn sich die Property des alten und neue Datenobjektes ändert. Ein weiterer Nachteil ist, dass ein gebindetes Datenobjekt nicht von der Garbage Collection gelöscht werden kann solange das Binding existiert.</p>
<p>Um ein über die BindingUtils-Klasse erstelltes Binding zu entfernen muss die ChangeWatcher-Instanz, die die Klasse bei der Erstellung eines Bindings zurück gibt aufgehoben werden. Über diese Instanz kann das Binding gelöscht werden. Benötigt ein ItemRenderer mehr als ein Binding müssen die ChangeWatcher-Instanzen in einer Liste gespeichert werden um diese später wieder aufzuheben.<br />
Das könnte in etwa so aussehen:</p>
<pre class="brush: as3;">
private var _changeWatcherList:Array = new Array();

override public function set data(value:Object):void
{
	if (value != data)
	{
		super.data = value;

		// remove old bindings
		for (var i:int = 0; i &lt; _changeWatcherList.length; i++)
		{
			ChangeWatcher(_changeWatcherList[i]).unwatch();
		}
		_changeWatcherList = new Array();

		// create new bindings
		_changeWatcherList.push( BindingUtils.bindSetter( onProperty1Changed, value, &quot;property1&quot; ) );
		_changeWatcherList.push( BindingUtils.bindSetter( onProperty2Changed, value, &quot;property2&quot; ) );
		_changeWatcherList.push( BindingUtils.bindSetter( onProperty3Changed, value, &quot;property3&quot; ) );
	}
}
</pre>
<p>Man sieht an diesem Beispiel, das einige Zeilen mehr Code notwendig sind um die erstellten Bindings zu verwalten. Für diesen Zweck habe ich eine Klasse geschrieben die Bindings erstellt und in einer Liste speichert um diese später über die Methode &#8220;clear&#8221; zu löschen.</p>
<pre class="brush: as3;">
private var _bindingMap:IBindingMap = new ArrayBindingMap();

override public function set data(value:Object):void
{
	if (value != data)
	{
		super.data = value;
		// remove old bindings
		_bindingMap.clear();
		// create new bindings
		_bindingMap.bindSetter( onProperty1Changed, value, &quot;property1&quot; );
		_bindingMap.bindSetter( onProperty2Changed, value, &quot;property2&quot; );
		_bindingMap.bindSetter( onProperty3Changed, value, &quot;property3&quot; );
	}
}
</pre>
<p>Die BindingMap-Klasse findet ihr <a href='http://blog.reppa.net/wp-content/uploads/2011/05/BindingUtils.zip'>hier</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reppa.net/2011/04/itemrenderer-bindingutils-und-garbage-collection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Klickbarer Flex-DataGrid Header</title>
		<link>http://blog.reppa.net/2010/11/klickbarer-flex-datagrid-header/</link>
		<comments>http://blog.reppa.net/2010/11/klickbarer-flex-datagrid-header/#comments</comments>
		<pubDate>Thu, 25 Nov 2010 08:52:40 +0000</pubDate>
		<dc:creator>Daniel Schmidt</dc:creator>
				<category><![CDATA[Actionscript]]></category>
		<category><![CDATA[Flex]]></category>
		<category><![CDATA[DataGrid]]></category>
		<category><![CDATA[DataGridHeader]]></category>

		<guid isPermaLink="false">http://blog.reppa.net/?p=77</guid>
		<description><![CDATA[Flex Datagrid-Header bieten von Haus aus keine Möglichkeit auf Click-Events der Maus zu reagieren. Um den Mausklick auf den ColumnHeader eines Datagrids festzustellen, muss dafür die Klasse mx.controls.dataGridClasses.DataGridHeader erweitert werden die vom Datagrid zur Darstellung des Headers verwendet wird. Innerhalb &#8230; <a href="http://blog.reppa.net/2010/11/klickbarer-flex-datagrid-header/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Flex Datagrid-Header bieten von Haus aus keine Möglichkeit auf Click-Events der Maus zu reagieren.</p>
<p><a href="http://blog.reppa.net/wp-content/uploads/2010/11/headerColumn.png"><img class="aligncenter size-full wp-image-78" src="http://blog.reppa.net/wp-content/uploads/2010/11/headerColumn.png" alt="" width="317" height="177" /></a>Um den Mausklick auf den ColumnHeader eines Datagrids festzustellen, muss dafür die Klasse <code>mx.controls.dataGridClasses.DataGridHeader</code> erweitert werden die vom Datagrid zur Darstellung des Headers verwendet wird. Innerhalb dieser Klasse wurden die Methoden <code>mouseDownHandler</code> und <code>mouseUpHandler</code> überschrieben. Dadurch ist es möglich, den Mausklick des Headers über das Datagrid dem User mitzuteilen.</p>
<p>Das modifizierte Datagrid kann wie folgt verwendet werden:</p>
<pre class="brush: as3;">
&lt;mx:Script&gt;
		&lt;![CDATA[
		import mx.events.DataGridEvent;

		private function onHeaderClicked(event:DataGridEvent):void
		{
			this.output.text = &quot;index=&quot; + event.columnIndex + &quot; \theaderText='&quot; + event.itemRenderer.data.headerText + &quot;'&quot;;
		}
		]]&gt;
	&lt;/mx:Script&gt;

	&lt;local:ExtendedDataGrid
		headerClicked=&quot;this.onHeaderClicked(event);&quot;
		selectionColor=&quot;0xFF0000&quot;
		sortableColumns=&quot;false&quot;
		draggableColumns=&quot;false&quot;&gt;
		&lt;local:columns&gt;
			&lt;mx:DataGridColumn headerText=&quot;Col A&quot; /&gt;
			&lt;mx:DataGridColumn headerText=&quot;Col B&quot; /&gt;
			&lt;mx:DataGridColumn headerText=&quot;Col C&quot; /&gt;
		&lt;/local:columns&gt;
	&lt;/local:ExtendedDataGrid&gt;

	&lt;mx:Label id=&quot;output&quot; textAlign=&quot;center&quot; width=&quot;100%&quot; text=&quot;click on a column-header&quot; /&gt;
</pre>
<p>Der Quellcode zu diesem Beispiel kann <a href='http://blog.reppa.net/wp-content/uploads/2010/11/ClickableDataGridHeader.zip'>hier</a> heruntergeladen werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.reppa.net/2010/11/klickbarer-flex-datagrid-header/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

