Action Script 3 Thumbnailcontainer zeigt nur letztes Bild an

The Gone

Grünschnabel
Liebe Flasher,

Ich bastel gerade an einer dynamischen Galerie mit Kategoriesystem. Jetzt möchte ich thumbnails von den Bildern in einen Container stecken. Die Bilder werden alle brav geladen, aber angezeigt wird immer nur das letzte. Ich nehme an, das es daran liegt, dass der "ImgEventHandler" nur das letzte Bild bekommt.

Meine frage lautet also: Wie schaffe ich es, dass der "ImgEventHandler" jedes bekommt?

Die Container Klasse:
Code:
package container{
	
	import flash.display.*;
	import flash.events.*;
	import loaders.GetCatXML;
	import loaders.PicLoader;
	import dispatcher.*;
	import container.Thumb;
	
	public class CatCont extends MovieClip{
		
		public var thumbCounter:uint = 0;
		
		public var catXMLLoader = new GetCatXML;
		
		public static var thePicWidth:uint;
		public static var thePicHeight:uint;
		public static var thePicStartX:uint;
		public static var thePicStartY:uint;
		public static var thePicSpaceX:uint;
		public static var thePicSpaceY:uint;
		public static var thePicMaxX:uint;
		public var countX:uint = 0;
		public var countY:uint = 0;
		
		thePicWidth = 110;
		thePicHeight = 110;
		thePicStartX = 10;
		thePicStartY = 10;
		thePicSpaceX = 10;
		thePicSpaceY = 10;
		thePicMaxX = 5;
		
		function CatCont(){
			addChild(catXMLLoader);
			
			catXMLLoader.addEventListener(XMLisArray.CONTROL_TYPE,catsEventHandler);
		}
		
		function catsEventHandler(key:String){
			var i:uint;
			
			for(i = 0; i < this.catXMLLoader.theCatsArray.length; i++){
				var thePic:MovieClip;
					thePic = new MovieClip;
					thePic.scaleX = 0.5;
					thePic.scaleY = 0.5;
		
				var img:PicLoader;
					img = new PicLoader("../images/" + this.catXMLLoader.theCatsArray[i].src);
					img.addEventListener(ImgIsLoaded.CONTROL_TYPE,ImgEventHandler);
					
				var imgArray:Array = new Array();
				imgArray.push(img);		
			}
			
			function ImgEventHandler(){
				thePic.addChild(img);
				
				var aThumb:Thumb;
					aThumb = new Thumb;
					aThumb.x = (thePicStartY + (thumbCounter*aThumb.width) + (thumbCounter*thePicSpaceX));
					aThumb.addChildAt(thePic,0);
					
				if(thePic.width < 220){
					thePic.x = (aThumb.width - thePic.width)/2;
				}
				if(thePic.height < 220){
					thePic.y = (aThumb.height - thePic.height)/2;
				}
				
				addChild(aThumb);
	
				thumbCounter++;
			}
		}
	}
}

Der PicLoader:
Code:
package loaders{
	
	import flash.display.*;
	import flash.net.URLRequest;
	import flash.events.*;
	import dispatcher.ImgIsLoaded;
	
	public class PicLoader extends MovieClip{
		
		function PicLoader(theSrc:String){

			var thePicLoader:Loader;
			thePicLoader = new Loader;
			
			applyListeners(thePicLoader.contentLoaderInfo);
			
			var theUrlRequest:URLRequest;
			theUrlRequest = new URLRequest(theSrc);
			
			thePicLoader.load(theUrlRequest);
			
			addChild(thePicLoader);
		}
		
		private function applyListeners(dispatcher:IEventDispatcher):void{
			dispatcher.addEventListener(Event.COMPLETE, completeHandler);
		}
		
		private function completeHandler(event:Event):void {
			dispatchEvent(new ImgIsLoaded('ImgIsLoaded'));
		}
	}
}

Der ImgIsLoaded Dispatcher:
Code:
package dispatcher{
	import flash.events.Event;
	
	public class ImgIsLoaded extends flash.events.Event{
		public static const CONTROL_TYPE:String = "ImgIsLoaded";
		private var command:String;
		
		public function ImgIsLoaded(command:String){
			super(CONTROL_TYPE);
			this.command = command;
		}
	}
}

Mit den besten Wünschen
Gone
 
Ich hab jetzt nicht deinen ganzen Code durchgesucht, aber ich könnte mir vorstellen dass es daran liegt, dass du die Funktion ImgEventHandler() in catsEventHandler() Funktion liegt. Sowas ist nicht sehr effizient, da die Funktion nur am Ende des for-loops ausgeführt wird, desshalb erscheint warscheinlich nur das letzte Bild.

Gruss
 
Hi,

Du greifst in der Funktion "ImgEventHandler" auf das Objekt "theImg" zu - dieses wird in der Schleife der umgebenden Funktion allerdings bei jedem Durchlauf neu belegt, so dass zum Zeitpunkt des Aufrufs von "ImgEventHandler" nur noch der letzte aktuelle Wert in dem Objekt zu finden ist.

Du solltest dem Konstruktur von "ImgIsLoaded" die aktuelle Referenz auf "thePic" übergeben, welche die Klasse dann an den EventHandler weitergibt.

Gruß
.
 
Hi,

@oaki
Vielen Dank für Deinen Input! Ursprünglich war es so geplant,wie Du es vorschlägst,aber ich bekomme dann immer die Ausgabe, dass ich auf eine undefinierte Eigenschaft zugreifen möchte. Also habe ich hier eine Quik'n'Dirty Variante gewählt, um mich nachher mit diesem Problem auseinander zu setzen.

@Tobias Menzel
Auch Dir ein großes Dankeschön! So etwas in der Art, habe ich mir gedacht. Ich habe im Moment leider keinen Plan wie ich das anstellen soll. So wie ich mich kenne ist das wahrscheinlich eine total einfache Sache, aber alles was ich bis jetzt in dieser Richtung versucht habe war zum Scheitern verurteilt. Wahrscheinliche schramme ich mit meiner jetzigen Bitte ganz massiv in ein explizietes DON'T dieses Forums aber vielleicht kannst Du mir erklären oder zeigen, wie ich die Objektreferenz weitergebe, oder vielleicht weißt Du einen Link wo dieses Thema behandelt wird.

Nochmals vielen Dank an euch beide!

Mit den besten Wünschen
Gone
 
Wahrscheinliche schramme ich mit meiner jetzigen Bitte ganz massiv in ein explizietes DON'T dieses Forums
das nicht (für solche Fragen ist das Forum ja da) - aber ich muss gestehen, mich bislang noch zu wenig mit EventDispatchern befasst zu haben, um eine Lösung einfach aus dem Stehgreif zu posten.

Wenn Du eine lauffähige Version des Dings (inklusive aller Komponenten und der XML-Quelle) postest, die unter Flash 8 lauffähig ist (arbeitest Du mit CS3?), kann ich mich mal ransetzen, und einen Vorschlag erarbeiten.

Gruß
.
 
Hi,
Das ist ja ganz fantastisch was Du mir anbietest! Vielen Dank! Beim speichern als Flash8 Dokument sagt er mir leider, dass Daten mit der Bezeichnung "action script 3" verloren gehen(kann Flash8 mit AS3 umgehen?) also hier einmal das Projekt mit drei Beispielbildern als Flash9.

Mit den besten Wünschen
Gone
 

Anhänge

Hi Gone,

Meine Güte :)

Ich habe den code in der CatCont und PicLoader Klasse so geändert, dass es nun funktioniert. Hier der Code, und die Datei:

Code:
package loaders{
	
	import flash.display.*;
	import flash.net.URLRequest;
	import flash.events.*;
	import dispatcher.ImgIsLoaded;
	
	public class PicLoader extends MovieClip {
		
		private var _thePicLoader:Loader;
		
		function PicLoader(theSrc:String){
					
			_thePicLoader = new Loader();
			addChild(_thePicLoader);
			_thePicLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
			
			var theUrlRequest:URLRequest;
			theUrlRequest = new URLRequest(theSrc);
			
			_thePicLoader.load(theUrlRequest);
		}
		

		private function completeHandler(event:Event):void {
			trace("pic loaded!");					
		}
		
	}
}

Code:
package container{
	
	import flash.display.*;
	import flash.events.*;
	import loaders.GetCatXML;
	import loaders.PicLoader;
	import dispatcher.*;
	import container.Thumb;
	
	public class CatCont extends MovieClip{
		
		public var thumbCounter:uint = 0;
		
		public var catXMLLoader = new GetCatXML();
		
	
		
		function CatCont(){
			addChild(catXMLLoader);
			
			catXMLLoader.addEventListener(XMLisArray.CONTROL_TYPE, catsEventHandler);
			
			
		}
		
		function catsEventHandler(key:String){
			var i:uint;
			
			for(i = 0; i < this.catXMLLoader.theCatsArray.length; i++){
							
				var img:PicLoader;
					img = new PicLoader("../images/" + this.catXMLLoader.theCatsArray[i].src);
					img.x = i * 200;
					addChild( img );			
			}
				
		}
	}
}

Also nur das wir uns richtig verstehen: Der Code ist immer noch sehr unsauber und es hat noch viele unlogische Parts drin, die besser zu lösen wären. Habe leider keine Zeit dies auch noch zu korrigieren, aber erstmal ist dein Problem gelöst.

Gruss
 

Anhänge

Hi oaki,

Vielen Dank für Deine Bemühungen! So ist das natürlich gleich viel feiner! Die Sache ist die, dass ich gerne jedes Bild in einem Rahmen hätte in dem das Bild mittig postiert ist. Deswegen bin ich auf diese anscheinend sehr skurile Lösung gekommen. Aber jetzt wo ich bei Deinem Ansatz weiter mache haut alles so hin wie ich mir das vorgestellt habe... :)

Vielen Dank!

Ps: Wenn Du vielleicht noch weißt wie man eine Objektreferenz über einen selbstgestrickten EventDispatcher weitergibt... Das wäre sicher nicht nur für mich Interessant.

Mit den besten Wünschen
Gone
 
In AS3 kannst dem EventDispatcher keine Parameter übergeben.

Aber du kannst die Event-Klasse extenden und dort drin deine Variablen speichern und diese dann über event.target in dem EventHandler auslesen.
Code:
package {

import flash.events.Event;

public class MyEvent extends Event {

public var variable1:Object;

public function ( o:Object ) {

variable1 = o;

}

}
}

Gruss
 
Zurück