Beiträge der Kategorie flash/flex

Sound-Steuerung in Flash AS3

In Flash kann man relativ einfach Musik-Dateien (mp3) laden und abspielen. Ein Anleitung gibt es z.B. bei Republic of Code – Playing sounds with AS3. Nun wollte ich die Datei aber nicht von Anfang an abspielen, sondern ab einem Punkt, den ich mir vorher gemerkt habe. Die Seite, auf der das eingesetzt wird, verwendet Hintergrund-Sound mit ungefähr 2 Minuten langen Loops. Nun dachte ich mir, es sei ein wenig nervig, wenn beim Umherklicken auf der Seite die Hintergrund-Datei immer von vorne anfangen würde zu spielen. Daher wird beim Abspielen der Datei die aktuelle Position des Abspielknopfes gemerkt und beim nächsten Aufruf spielt die Musik von der Stelle weiter. Und daher musste ich die Musik nicht von vorn, sondern von einem bestimmten Zeitpunkt abspielen. Wenn der Loop fertig gespielt worden ist, sollte das Musikstück wieder von vorn beginnen. Nun gab es allerdings zwei Kleinigkeiten, die mir die Lösung nicht besonders einfach gemacht haben.

In der Flash-AS3-Referenz zum Sound-Objekt steht als Beschreibung der Funktion play()

public function play(startTime:Number = 0, loops:int = 0, sndTransform:SoundTransform = null):SoundChannel

loops:int (default = 0) — Defines the number of times a sound loops back to the startTime value before the sound channel stops playback.

Wenn die Datei also zu Ende abgespielt wurde, dann spring der Abspielknopf nicht an den Anfang, sondern an die Position, mir der das Abspielen begann. D.h. soundClip.play(position, 10000) funktioniert in meinem Fall nicht, weil da der Sound immer nur von position bis Ende abgespielt wurde.

Dann entschloss ich mich auf die Angabe von Loops zu verzichten und stattdessen einen Event Listener zu nehmen, der auf das Event SOUND_COMPLETE hört. Dieser Event Listener wird dem Sound Channel-Objekt zugewiesen. Leider wurde das Event nicht ausgelöst, was der folgende Artikel SOUND_COMPLETE event is not firing beschreibt und löst. Bei jedem Aufruf der Funktion play wird ein neues Sound Channel-Objekt zurück gegeben, so dass der Event Listener gelöscht wird. Damit es also wie gewünscht funktioniert, muss auf jeden Aufruf von play() der Aufruf addEventListener() folgen.

Tile Container Komponente

Die Tile Komponente ist ein Container, in dem die Elemente automatisch horizontal oder vertikal einsortiert werden. Im Vergleich zu einer HBox oder eine VBox, bei denen keine neue Zeile oder Reihe begonnen wird, wenn die Elemente die vorgegeben Breite bzw. Höhe des Containers überschreiten, sorgt Tile dafür, dass eine neue Zeile begonnen wird. Sehr gut geeignet dafür, wenn man eine variable Menge von Elementen mittels Repeater darstellen möchte. Die Dokumentation zu Tile mit Beispielen der Anordnung gibt es bei Adobe Flex 3 Referenz.

Geschrieben in flash/flex | Kommentare deaktiviert für Tile Container Komponente

Farbe einer Reihe im DataGrid abhängig von Inhalt setzen

In ein DataGrid wird eine Liste mit Daten geladen, dabei sind die Datensätze entweder aktiv oder deaktiviert, was durch 1 bzw. 0 in dem Feld active dargestellt wird. In dem DataGrid soll das so dargestellt werden, dass die Textfarbe der Einträge mit active=0 etwas blasser ist, als die Farbe der anderen Einträge. Eine lange Recherche ergab, dass man dieses nur mit Hilfe eines Item Renderers lösen kann.

MXML DataGrid:

<mx:DataGrid dataProvider="{filterData}">
	<mx:columns>
		<mx:DataGridColumn dataField="name" headerText="Name"
			itemRenderer="classes.ActiveItemRenderer" />
	</mx:columns>
</mx:DataGrid>

Dann im Ordner/Package classes die Klasse ActiveItemRenderer als Ableitung von Label anlegen und das setzen:

package classes
{
	import mx.controls.Label;
 
	public class ActiveItemRenderer extends Label
	{
		public function ActiveItemRenderer()
		{
			super();
		}
 
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
			super.updateDisplayList(unscaledWidth, unscaledHeight);
 
 			if(data.active == 0) {
				setStyle("color", 0x999999);
			}
		}
 
	}
}

Quelle: Formatting a flex datagrid control using a custom item renderer
Das hier habe ich aber auch gefunden:
How to change datagrid’s row background color
Changing text color in a datagrid using item renderers

Tags: ,

Geschrieben in flash/flex | Kommentare deaktiviert für Farbe einer Reihe im DataGrid abhängig von Inhalt setzen

Flash Cache löschen

Flash hinterläßt die Dateien nicht wie gedacht im Browser-Cache, sondern in einem eigenen Cache, den man nicht einfach löschen kann. Es gibt von Adobe einen Settings Manager, der es ermöglich, diesen Cache zu verwalten und die Dateien zu löschen.
Adobe Fash Settings Manager
Tutorial: Tutorial: „How to delete your flash cache“

Noch ein Tipp von mir: Wenn nach mehrmaligem hochladen und Browser-Cache-Löschen und Flash-Cookie löschen und verzweifeln, die Flash-Animation immer noch die alte ist, dann die Url der Flash-Datei direkt in die Adresszeile schreiben (wenn man sie nicht kennt, dann Firebug zu Hilfe nehmen) und dahinter einen Get-Parameter hängen. Beispiel: main.swf?test01. Das veranlasst den Browser, die Datei neu vom Server zu Laden und nicht aus dem Cache.

Inhalt einer Fehlerantwort vom Server ausgeben

… oder handling faultevent content in flash.

Wenn man Daten aus Flash/Flex an ein PHP-Skript schickt und diese dort verarbeitet, schickt man in der Regel ein Ergebnis zurück in einem HTTP Response mit Status Code 200. Diese Antwort kann man ganz leicht ausgeben.

XML-Request anlegen:
// Request Objekt initialisieren
xmlRequest = new HTTPService();
xmlRequest.resultFormat = "e4x";
xmlRequest.method = "POST";
xmlRequest.addEventListener(ResultEvent.RESULT, requestResultHandler);
xmlRequest.addEventListener(FaultEvent.FAULT, requestFaultHandler);
xmlRequest.url = "http://www.example.com";
xmlRequest.send();

Antwort ausgeben:
public function requestResultHandler(event:ResultEvent):void
{
var returnXML:XML = event.result as XML;
}

Ein wenig schwieriger ist es mit anderen Status Codes, wie ich rausgefunden habe, werden diese vom Browser nicht an das Flash Plugin weitergeleitet, so dass es nur möglich ist, auf die Status Codes zu reagieren, nicht aber den Inhalt der Antwort auszugeben:
public function requestFaultHandler(event:FaultEvent):void
{
Alert.show("Es ist ein Fehler aufgetreten", "Fehler");
}

Quellen:
http://efreedom.com/Question/1-2299401/Actionscript-Expose-XML-Web-Service-FaultEvent-Can-Accessed
http://forums.adobe.com/thread/438755
http://blog.widget-labs.com/2007/02/15/handling-web-service-exception-in-flex-code/

Tags: , ,

Geschrieben in flash/flex | Kommentare deaktiviert für Inhalt einer Fehlerantwort vom Server ausgeben

Flash AS3: DuplicateMovieClip oder eine Clone-Funktion

Wie auf vielen Seiten im Web bereits beschrieben, sind es im Bezug auf MovieClip-Kopien zwei Dinge, die in Flash nicht funktioniert. In AS2 kann man zwar MovieClips kopieren, dann aber nicht einem anderen Parent-Objekt zuweisen. d.h. wenn die Verschachtelung wie folgt ist: A.B und ich mach eine Kopie von B mit dem Namen C, dann ist es immer noch A zugeordnet: A.B! Und es gibt keinen Weg, um das zu ändern.
In AS3 ist es einfach, den Parent eines Movie-Clips zu ändern:

a_mc.addChild(b_mc.c_mc);

Nach diesem Aufruf ist c_mc nun ein Unterobjekt von a_mc und nicht mehr von b_mc. Was in AS3 allerdings nicht so einfach ist, ist das Kopieren von MovieClips. Es gibt keine Clone-Funktion oder ähnliches. Bei meinen Recherchen bin im am Ende auf eine Seite gestoßen, die das was ich gefunden habe, ganz gut zusammenfasst: The Quest for MovieClip.clone(). Ich hatte vorhin schon die Lösung Nr.5 für mich ausgesucht: die Funktion duplicateDisplayObject. Das Beispiel funktioniert, sobald ich den Funktionsaufruf (mitsamt der Klasse) in meine Datei reinkopiert hatte, funktionierte es nicht. Der genaue Vergleich ergab, dass es wichtig ist, das zu kopierende Objekt als Klasse in Flash zu exportieren. Dazu beim Anlegen des MovieClips als Symbol oder unter Eigenschaften des Symbols in der Bibliothek den Haken bei „Für ActionScript“ exportieren setzen und einen Klassennamen angeben (der allerdings keine weitere Rolle spielt). Dann klappts auch mit der Kopie.

Tags: , , ,

Geschrieben in flash/flex | Kommentare deaktiviert für Flash AS3: DuplicateMovieClip oder eine Clone-Funktion

File Download mit AS3

Es gibt einige Beispiele dafür, wie man eine Datei aus Flex heraus zum Download anbietet. Allerdings gibt es dabei zwei Dinge zu beachten: Das FileReference-Objekt darf nicht innerhalb der Funktion instanziiert werden, in der der Download startet. Das Objekt ist dann nicht persistent und verschwindet wieder. Daher ist es wichtig, das Objekt direkt in der Klasse zu Deklarieren und zu instanziieren:

  1. public var fileRef:FileReference = new FileReference();

Zweitens muss man beachten, dass aufgrund der geänderten Sicherheitsrichtlinien der Dateidownload nur als Folge einer Benutzerinteraktion gestartet werden kann – z.B. einem Click.
In beiden Fällen werden keine Fehler ausgegeben, es funktioniert nur einfach nicht.

Es ist ohne weiteres möglich, eine Datei zum Download anzubieten, die von PHP erstellt wird. Dabei habe ich herausgefunden, dass z.B. der Header „Content-Type“ nicht gesetzt werden darf. Vielmehr wird der generierte Inhalt direkt an den Browser gesendet. Erlaubte Header sind z.B.:

  1. header("Content-Transfer-Encoding: binary");
  2. header("Cache-Control: no-cache, must-revalidate, max-age=60");
  3. header("Expires: Sat, 01 Jan 2000 12:00:00 GMT");
  4. print($content);

Geschrieben in flash/flex | Kommentare deaktiviert für File Download mit AS3

Busy Cursor in Flex anzeigen

Um einen Busy Cursor in Flex anzuzeigen (sieht aus wie eine kleine Uhr), muss man den CursorManager inkludieren:

  1. import mx.managers.CursorManager;

… dann kann man an jeder beliebigen Stelle im Code den Cursor aktivieren:

  1. CursorManager.setBusyCursor();

… und danach wieder ausschalten:

  1. CursorManager.removeBusyCursor();

Ein schönes Beispiel gibt es hier bei Flex Examples: Changing the cursor in a Flex application using the CursorManager class

UPDATE: es gibt nicht nur einen Cursor, sondern einen Cursor Stack. In dem oben verlinkten Beispiel kann man das sehr schön selbst sehen, wenn man mehrmals auf den Button „setBusyCursor“ mehrmals anklickt. Der Cursor verschwindet erst dann, wenn man genauso oft auf den Button „removeBusyCursor“ geklickt hat. Abhilfte schafft die Funktion removeAllCursors(), die alle Cursor entfernt.

Geschrieben in flash/flex | Kommentare deaktiviert für Busy Cursor in Flex anzeigen

Fehler beim Öffnen und Schließen von Fenstern mit dem PopUpManager

Bin wieder auf einen interessanten Fehler (Bug) gestoßen: Ich hatte ein TitleWindow, dass ich mit Inhalt befüllt habe und dessen Eigenschaft visible auf false gesetzt war. Beim Klick auf einen Button wurde das Fenster mittels visible=true eingeblendet, mit dem PopUpManager als PopUp Fenster hinzugefügt (PopUpManager.addPopUp(myTitleWindow)) und beim Klick auf einen anderen Button wieder ausgeblendet. Dabei wurde vor allem dann, wenn die Daten im Fenster recht umfangreich waren, ein Fehler geworfen: mal ein RangeError, mal ein Error den SystemManager betreffend.
Meine Recherche ergab, dass das ein bereits gemeldeter Bug ist: http://bugs.adobe.com/jira/browse/SDK-18290.
Die Lösung des Problem in meinem Fall, war das Fenster initial eingeblendet zu lassen, aber außerhalb des sichbaren Bereiches zu positionieren und dann mittels PopUpManager.centerPopUp zu zentrieren.

Geschrieben in flash/flex | Kommentare deaktiviert für Fehler beim Öffnen und Schließen von Fenstern mit dem PopUpManager

Fehler bei Laden von Modulen mit TabNavigator

Wenn man eine Anwendung mit Modulen entwickelt und eins der Module einen TabNavigator enthält, dann wird beim zweiten Aufruf des Moduls ein seltsamer Fehler ausgegeben:
TypeError: Error #1034: Typumwandlung fehlgeschlagen: mx.managers::HistoryManagerImpl@6283741 kann nicht in mx.managers.IHistoryManager umgewandelt werden.
Dieser Fehler ist bekannt, und ist laut diesem Artikel bereits gemeldet. Der auf der Seite vorgeschlagene Workaround funktioniert, dabei müssen die folgenden zwei Zeilen in die Hauptapplikation eingefügt werden.

  1. import mx.managers.HistoryManager;
  2. private var hist:HistoryManager;

http://www.object-factory.org/?p=46
http://bugs.adobe.com/jira/browse/SDK-15249
UPDATE: Das Problem scheint nicht nur im Bezug auf den HistoryManager, sondern auch auf den DragManager aufzutreten. Der Quickfix sind die zwei Zeilen, nur mit DragManager anstatt HistoryManager.

Geschrieben in flash/flex | Kommentare deaktiviert für Fehler bei Laden von Modulen mit TabNavigator