Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

DanielGianni

[Resolvido]Eventos - Disparando evente dentro da classe

Recommended Posts

Estou criando um formulário de perguntas para alunos, não posso usar os componentes originais do flash porque como utilizo cada frame como um página do questionário os componentes não se comportam de maneira correta quando eu adiciono um stop em cada frame (não tem como eu mudar isso porque é o processo de passar páginas depende dessa ordem).

 

bom colocando esta observação acima para eliminar comentários do tipo "você está querendo reinventar a roda"... rsrsr vamos lá... a tela é mais ou menos assim (a de teste)

 

 

Imagem Postada

 

Este é o código que está no STAGE

 

stop();

import com.teste.*;

var choices:Array = new Array();
var respostasAlunos:Array = new Array();

choices[0] = new Array("opção 1","opção 2","opção 3", "opção 4");

//
// abaixo adicionando o evento para o primeiro textinput
//
fr001_ch001.addEventListener(MouseEvent.MOUSE_DOWN, function() {

var resposta1:ListaOpcoes = new ListaOpcoes();
resposta1.vetorOpcoes=choices[0]; // <=== este é um setter para passar o vetor que serve para montar as opções
resposta1.montaOpcoes(fr001_ch001,root); // <==== eu passo quem é o componente pai e o root, para pegar dados sobre ele (x,y,width,heigth)

});


//
// abaixo adicionando o evento para o segundo textinput
//

fr001_ch002.addEventListener(MouseEvent.MOUSE_DOWN, function() {

var resposta2:ListaOpcoes = new ListaOpcoes();
resposta2.vetorOpcoes=choices[0]; // <===== estou usando a mesma lista de opções para economizar trabalho com os testes
resposta2.montaOpcoes(fr001_ch002,root);

});

trace("escolheu "+respostasAlunos[0]+","+respostasAlunos[1]); <=== sei que isso não funciona só coloquei a título de futuras depurações quando tiver tudo ok

E esta é a classe

 

package com.englishcorporation{

	 /*
	 // ListaOpcoes()
	 // Versão 1.0 - 30/01/2010 - Criação da Classe
	 //                           
	 //
	 // Esta classe faz:
	 //
	 // 1) Cria uma lista de opções no estilo menu pulldown
	 // 2) Recebe uma matriz das opções:
	 //    - texto da opção 
	 // 3) Retorna a opção escolhida pelo clique do usuário.
	 */
	 
	public class ListaOpcoes {
		
		import flash.events.*;
		import flash.text.*;
		import flash.display.MovieClip;
		 
		private var _vetorOpcoes:Array = new Array();
		private var _instancias:Array = new Array();
		private var _escolha:String = new String();
		private var _x:Number = new Number();
		private var _y:Number = new Number();
		private var _width:Number = new Number();
		private var _height:Number = new Number();
		private var _objetoOrigem:Object = new Object();
		private var _root:Object = new Object();
		
		public function ListaOpcoes() {
			
		}

		// função SET que recebe o vetor com as opções para montar na tela 
                // (não coloquei no construtor porque suspeito que será preciso extender a classe events e esse negócio 
                // de sobreescrever construtor de classes do package do flash não me trás boas recordações rs)
		public function set vetorOpcoes(vetor:Array):void
		{
			if ( vetor.length > 0 )
			{
				_vetorOpcoes = vetor;
	
			}
		}
		
		// monta as opções na tela
		public function montaOpcoes(objetoPai:Object,objetoRoot:Object):void
		{
			if ( _vetorOpcoes.length > 0 && objetoPai != null )
			{
				_x = objetoPai.x;
				_y = objetoPai.y;
				_width = objetoPai.width;
				_height = objetoPai.height;
				_objetoOrigem = objetoPai;
				_root = objetoRoot;
				
				removeInstancias();
				
				for ( var indice:String in _vetorOpcoes ) {

					var opcao:TextField = new TextField();
					opcao.type = TextFieldType.DYNAMIC;
					opcao.width = 100;
					opcao.height = 20;
					opcao.background = true;
					opcao.border = true;
					opcao.type = TextFieldType.DYNAMIC;
					opcao.text = _vetorOpcoes[indice];
					opcao.x = _x;
					opcao.y = _y + _objetoOrigem.height;
					_y = opcao.y;
	
					_root.addChild(opcao);
					_instancias.push(opcao);
					
					opcao.addEventListener(MouseEvent.CLICK, escolha);
						
				} // fim foreach
			}
		} // fim da função montaOpcoes

		// função para remover instâncias
		private function removeInstancias():void {

			for (var i:uint=0; i<_instancias.length; i++) {
				trace("Removeu ["+_instancias[i].name + "]");
				_root.removeChild(_instancias[i]);
			}
			_instancias = new Array();

		}	

		// função que retorna a escolha
		private function escolha(e:MouseEvent):void {

			trace("clicou em [" + e.target.name + "] que tem o valor [" + e.currentTarget.text + "]");
			removeInstancias();
			_escolha = e.currentTarget.text; // <====== acho que eu precisava disparar um evento aqui
			
		}
	
	} // fim da classe
	
} // fim do package


 

1) O problema principal consiste em retornar o valor que foi escolhido pelo clique, acredito que eu precise criar um evento e dispará-lo dentro da classe para lá no stage eu poder pegar o resultado quando for clicada a opção. Eu não sei como fazer isso!

 

Outros 2 problemas menos relevantes são:

2) não consegui projetar uma lógica para montar as opções de forma a não ultrapassarem o limite da tela.

3) não consegui remover todas as instância dos objetos (das opções) antes de criar as novas da próxima pergunta, porque cada pergunta é uma instância independente da classe.

 

Alguém já utilizou alguma técnica parecida para retornar valores quando acontece determinado valor da classe para o stage????

(se o as3 aceitasse passagem de variáveis por valor ficava fácil, mas tudo é por referência)

 

Esse artigo aqui do Imaster do Leandro Amano é muito bom sobre isso, mas não caiu a ficha de como eu posso retornar algum valor!!

 

http://imasters.com.br/artigo/8397/actionscript/disparando_um_evento_customizado/imprimir/

Compartilhar este post


Link para o post
Compartilhar em outros sites

tentou criar a classe para o evento personalizado?

 

dentro da classe voce pode ter um atributo, que guarde o valor desejado. Que no caso poderia ser passado pelo construtor, no momento do dispatchEvent.

 

algo assim:

 

public class SeuEvento extends Event{

 public var _valor:String; //coloquei publica para facilitar, mas e bom trabalhar com setter e getter
 static const QUESTAO_RESPONDIDA:String = "questao foi respondida";

	public function SeuEvento(pTipo:String, pValor:String){
 	_valor = pValor;
 	super(pTipo); //fiz simples, sem os outros parametros pra exemplificar
 }
}

Na classe ListaOpcoes voce dispara o evento, passando o valor da opcao que foi respondida:

 

var resposta = e.currentTarget.text; //como esta na sua classe
dispatchEvent(new SeuEvento(SeuEvento.QUESTAO_RESPONDIDA, resposta));

e la no palco voce pega esse valor no handler:

 

resposta2.addEventListener(SeuEvento.QUESTAO_RESPONDIDA, questaoRespondida_Handler);
function questaoRespondida_Handler(e:SeuEvento){
 	trace(e._valor);
}

 

Ou entao poe o valor em um atributo da propria classe ListaOpcoes, e o disparo do evento vai servir so como aviso...

Compartilhar este post


Link para o post
Compartilhar em outros sites

[RESOLVIDO] Muito obrigado, estudando seu exemplo descobri um macete, não precisa extender a classe Event, já usa direto a EventDispatcher

 

Código no Stage

stop();

import flash.text.*;
import com.teste.*;

var instanciasObjetos:Array = new Array();
var choices:Array = new Array();
var respostasAlunos:Array = new Array();

choices[0] = new Array("opção 1","opção 2","opção 3", "opção 4");

var resposta1:ListaOpcoes = new ListaOpcoes();
resposta1.addEventListener("ESCOLHEU", function(e:Event) {    // <=== aqui está o pulo do gato, mapeando o evento da escolha lá da classe 
	trace("escolheu "+e.target.escolhido);
	instanciasObjetos = new Array(); // <==== aqui reinicia o vetor de objetos (um garbage collector tabajara) 
});

fr001_ch001.addEventListener(MouseEvent.MOUSE_DOWN, function() {
	resposta1.vetorOpcoes=choices[0];
	resposta1.montaOpcoes(fr001_ch001,root,instanciasObjetos);
});

var resposta2:ListaOpcoes = new ListaOpcoes();
resposta2.addEventListener("ESCOLHEU", function(e:Event) {
	trace("escolheu "+e.target.escolhido);
	instanciasObjetos = new Array();
});
fr001_ch002.addEventListener(MouseEvent.MOUSE_DOWN, function() {
	resposta2.vetorOpcoes=choices[0];
	resposta2.montaOpcoes(fr001_ch002,root,instanciasObjetos);
});


Código da Classe

package com.englishcorporation{
		
	import flash.events.*;
	import flash.text.*;
	import flash.display.MovieClip;

	 /*
	 // ListaOpcoes()
	 // Versão 1.0 - 30/01/2010 - Criação da Classe
	 //                           
	 //
	 // Esta classe faz:
	 //
	 // 1) Cria uma lista de opções no estilo menu pulldown
	 // 2) Recebe uma matriz das opções:
	 //    - texto da opção 
	 // 3) Retorna a opção escolhida pelo clique do usuário.
	 */
	 
	public class ListaOpcoes extends EventDispatcher {
		 
		private var _vetorOpcoes:Array = new Array();
		private var _instancias:Array = new Array();
		private var _escolha:String = new String();
		private var _x:Number = new Number();
		private var _y:Number = new Number();
		private var _width:Number = new Number();
		private var _height:Number = new Number();
		private var _objetoOrigem:Obj
		// função GET que retorna a opção escolhida           <===== um getter para pegar o retorno é fundamental!!!
		public function get escolhido():String {
			return _escolha;
		}
		// função SET que recebe o vetor com as opções para montar na tela 
		public function set vetorOpcoes(vetor:Array):void
		{
			if ( vetor.length > 0 )
			{
				_vetorOpcoes = vetor;
			}
		}
		
		public function montaOpcoes( objetoPai:Object, objetoRoot:Object, objetoInstancias:Array ):void  // <==== precisou receber o vetor de objetos
		{
			if ( _vetorOpcoes.length > 0 && objetoPai != null )
			{
				_x = objetoPai.x;
				_y = objetoPai.y;
				_width = objetoPai.width;
				_height =oRoot;
				_instancias = objetoInstancias; // <===== lembre-se que o flash passa por referência, isso facilita!
				
				removeInstancias();
				trace(_instancias.length);

				for each ( var indice:String in _vetorOpcoes ) {

					var opcao:TextField = new TextField();
					opcao.type = TextFieldType.DYNAMIC;
					opcao.width = 100;
					opcao.height = 20;
					opcao.background = true;
					opcao.border = true;
					opcao.type = TextFieldType.DYNAMIC;
					opcao.text = indice;
					opcao.x = _x;
					opcao.y = _y + _objetoOrigem.height;
					_y = opcao.y;
	
					_root.addChild(opcao);
					_instancias.push(opcao);
					
					opcao.addEventListener(MouseEvent.CLICK, escolha);
						
				} // fim foreach
			}
		} // fim da função montaOpcoes

		// função para remover instâncias
		private function removeInstancias():void {

			for ( var indice in _instancia) {
    		                if ( _instancias[indice] != "LIXO" ) {  <======= Criando uma marcação de Lixo depois no Stage dar um new Array
					trace("Removeu ["+_instancias[indice].name + "]");
					_root.removeChild(_instancias[indice]);
					_instancias[indice]="LIXO";
				} 
				
			}

		}	

		// função que retorna a escolha
		private function escolha(e:MouseEvent):void {

			trace("clicou em [" + e.target.name + "] que tem o valor [" + e.currentTarget.texurrentTarget.text;
			dispatchEvent(new Event("ESCOLHEU")); <==== Olha só que legal! fica mais simples assim...
			
		}
	
	} // fim da classe
	
} // fim do package


Compartilhar este post


Link para o post
Compartilhar em outros sites

uma desvantagem eh que você perde a verificação do tipo de dado (enviando um objeto Event 'genérico'), mas realmente pra um projeto não mto grande pode ser mais simples...

 

cuidado com o uso de literais no tipo do evento, um erro de digitação pode dar dor de cabeça =)

 

no mais, ótimo que resolveu...

 

[]s

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.