Mostrando postagens com marcador AS3. Mostrar todas as postagens
Mostrando postagens com marcador AS3. Mostrar todas as postagens

quarta-feira, 19 de janeiro de 2011

Criação dinâmica - Exemplo prático

Neste post quero apresentar um exemplo prático de criação dinâmica de objetos.

No exemplo irá aparecer uma tela de login, aqui a idéia é simular uma requisição ao servidor para validar o login e retornar o menu de opções conforme o perfil do usuário e outras informações.
Para facilitar as coisas ao clicar no botão de login será requisitado um arquivo login.xml local, neste caso, deixei pronto um arquivo admin.xml e a senha pode ser qualquer coisa.
Uma vez que a tela de login carregar o arquivo xml aviso via evento customizado (LoginEvent) a application enviando os dados do xml carregado para montar o menu e as informações de como configurar os objetos a serem criados dinamicamente.

Pode-se alterar o arquivo admin.xml, criar outros arquivos .xml, ver com outras opções de menu (cada opção abre uma WindowDynamic que herda de TitleWindow a qual se configura e cria os objetos filhos dinamicamente) e outros controles - só alguns forão registrados em código, por isso, dependendo do controle que você quiser usar terá que registrá-lo primeiro.


Estou usando também o pattern
Singleton para guardar informações pertinentes do usuário (class AppSingleton.as).

A aplicação rodando pode ser vista aqui (view source com o botão direito do mouse habilitado).

Veja também:
Criação dinâmica de objetos com RSL

terça-feira, 28 de dezembro de 2010

Criação dinâmica de objetos com RSL

No meu post Criação dinâmica de objetos mostrei os passos para este tipo de criação.

Naquele post digo que é necessário o registro das classes dos objetos a serem criados dinamicamente para o compilador "saber" quais classes compilar. Isto é válido quando a opção Project > Properties > Flex Build Path > Library Path > Framework Linkage está marcado como Merged into code.

Quando a opção Framework Linkage está marcada como Runtime shared library (RSL) o registro não é necessário porque todo o framework estará junto (normalmente) com o swf da aplicação. Com isso podemos criar objetos dinamicamente da seguinte forma:

Flex 3
import mx.core.UIComponent;
import flash.utils.getDefinitionByName;

private function createButton():void {
var clazz:Class = getDefinitionByName("mx.controls.Button") as Class;
var instance:UIComponent = new clazz() as UIComponent;
addChild(instance);
}

Flex 4
import mx.core.UIComponent;
import spark.skins.spark.ButtonSkin;
import flash.utils.getDefinitionByName;

private function createButton():void {
var clazz:Class = getDefinitionByName("spark.components.Button") as Class;
var instance:UIComponent = new clazz() as UIComponent;
instance.setStyle("skinClass", spark.skins.spark.ButtonSkin);
addElement(instance);
}

A diferença entre o Flex 3 e 4 é que no 4 se não for definido o skinClass dará um erro no addElement informando que não foi possível encontrar o skin, o que vejo como um bug o qual reportei aqui (mais votos mais fácil o Flex Team dar uma olhada).

quarta-feira, 4 de agosto de 2010

Client.Message.Encoding

A metatag RemoteClass é usada no topo de uma classe AS para indicar a sua classe espelho Java (ou outra linguagem server) quando se usa RemoteObject.

Para facilitar, normalmente se cria a classe AS com mesmo nome e no mesmo pacote da sua correspondente java. Para usar remoteobject as classes AS e Java precisam ter um método construtor sem parâmetros e os atributos precisam ter o mesmo nome e precisam ser públicos ou com métodos get / set públicos.

Numa aplicação uma classe AS estava num pacote diferente da sua correspondente Java. Quando acesso um método remoto que retorna um objeto desta classe do Java para o Flex vem tipada corretamente, mas quanto tento enviar de Flex para Java dá um fault onde faultCode = Client.Message.Encoding e faultString = Cannot create class of type 'packageAS.classeAS'.

Este erro me chamou a atenção porque sempre imaginei que era só usar o atributo alias de RemoteClass [RemoteClass(alias="pacoteServer.classeServer")] apontando para a classe sever corretamente que iria funcionar, mas no fim o pacote e nome da classe precisam ser iguais.

Procurando na documentação algo que explicasse este fato não encontrei nada, mas achei algo interessante: "In the ActionScript class, you use the [RemoteClass(alias=" ")] metadata tag to create an ActionScript object that maps directly to the Java object." Isto é, usar alias com um espaço em branco vincula com sua classe server com mesmo pacote e mesmo nome de classe.

quarta-feira, 9 de junho de 2010

Locale pt_BR

O Flex utiliza fortemente internacionalização (i18n). Os componentes Alert, DateChooser, DateField, validadores, formatadores, entre outros permitem que suas propriedades que estão vinculadas ao idioma / locale sejam alteradas via código, alguns exemplos:
  • Alert: cancelLabel, noLabel, okLabel e yesLabel.
  • DateChooser e DateField: dayNames e monthNames.
  • Formatadores e Validadores (classes Formatter e Validator e suas classes filhas): possuem propriedades terminadas em error que são as mensagens que irão ser mostradas de acordo com a situação.
  • Os formatadores possuem a propriedade formatString (com exceção de CurrencyFormatter e NumberFormatter) e outras propriedades específicas de cada formatador, tais como: decimalSeparatorFrom, decimalSeparatorTo, thousandsSeparatorFrom, thousandsSeparatorTo para CurrencyFormatter e NumberFormatter e currencySymbol para CurrencyFormatter.
  • Os validadores CurrencyValidator e NumberValidator possuem as propriedades: decimalSeparator e thousandsSeparator e currencySymbol para CurrencyValidator.
Mas o melhor é poder informar o idioma / locale e o Flex configurar "automagicamente" estas propriedades. Para informar os locales, você precisa na hora da compilação indicar qual ou quais locales irá utilizar, para isso você precisa ir em Project > Properties > Flex Compiler e na linha Additional compiler arguments colocar:
-locale pt_BR // Para usar somente pt_BR
ou
-locale=pt_BR,en_US // Para usar pt_BR e en_US

E para trocar de idioma em runtime usa-se:
resourceManager.localeChain = ['pt_BR'];

Os arquivos de locale do framework são arquivos .properties compactados dentro de arquivos .swc. No Flex / Flash Builder estes arquivos se encontram em builder_dir/sdks/sdk_version/frameworks/locale e quando se estiver usando somente o sdk estará em sdk_dir/frameworks/locale. Se for necessário, você poderá abrir o arquivo .swc com qualquer descompactador e alterar o conteúdo dos arquivos .properties contidos nele.

Estes são exemplos do framework, você também pode criar traduções específicas para sua aplicação.

Veja mais

Introduction to localization
NumericInput (comentários)

Links para o locale pt_BR
No download do Flash Builder 4 e do SDK 4. Links de download aqui.
SVN atualizado (.properties) aqui e aqui.
Deixei disponível para download o do Flex 3 e 4.

sexta-feira, 14 de maio de 2010

Sombreamento de Classe

Conforme meu post anterior fiquei com poucas alternativas para contornar o meu problema:
  • Mudar o HTTPService.resultFormat para e4x.
  • Setar HTTPService.xmlDecode.
  • Alterar a classe SimpleXMLDecoder no SDK e compilar.
  • Esperar o Flex Team alterar SimpleXMLDecoder.simpleType no SDK para poder sobreescrever este método e tratar os dados da forma mais adequada para minha aplicação.
As duas primeiras opções seriam trabalhosas porque teria que fazer o mesmo que a classe SimpleXMLDecoder faz, isto é, transformar o resultado em object e isto seria necessário para evitar um impacto maior na minha aplicação já que esta espera este tipo de retorno. A terceira é delicada porque todo novo SDK teria que aplicar minhas alterações, compilar e distribuir para a equipe. E a última opção é a mais demorada.

Aí me lembrei de um conceito não muito utilizado, o Sombreamento ou Shadowing que também se aplica para Java. O que faria neste caso, criaria na minha aplicação o pacote mx.rpc.xml e nele copiaria a classe SimpleXMLDecoder do SDK e na primeira linha do método simpleType(val:Object) colocaria return val; com isso não seria feito o cast deixando sempre como String o que para minha aplicação atende plenamente. O detalhe aqui é que todo HTTPService que eu usar irá utilizar esta classe do meu projeto e não a sua correspondente no SDK e toda vez que sair um novo SDK terei que aplicar as alterações o que com o uso do SVN fica fácil identificar o que foi alterado e também a equipe ao atualizar o projeto já veria esta classe e suas atualizações.

sexta-feira, 29 de janeiro de 2010

Eventos do Flex ou Customizados

Frequentemente vejo nas listas de discussão a pergunta: como faço para acessar uma função / propriedade da minha janela (TitleWindow) através da application e vice-versa? Resumindo: como faço para trocar mensagens entre objetos?

Bem, para isso podemos usar Application.application ou as propriedades: parent, parentApplication, parentDocument ou owner, variando de acordo com os objetos que vão se comunicar.

Mas, esta não é a forma que eu recomendaria, a forma mais "elegante" é através do uso de eventos.

O Flex tem vários eventos próprios: eventos de ciclo de vida (add, added, preinitialize, initialize, creationComplete, updateComplete), MouseEvent, FocusEvent, KeyBoardEvent, entre outros ...Event e você também pode criar os seus próprios eventos customizando-os conforme sua necessidade.

Os eventos diminuem o acoplamento entre objetos tornando-os mais independentes e facilita o reaproveitamento de código. No evento customizado você pode criar as propriedades necessárias para enviar aos objetos que estiverem escutando, não precisando assim que um objeto saiba quais propriedades ou objetos o objeto que disparou o evento possue, só será necessário conhecer o evento monitorado.

Abaixo uma relação de links que exemplificam o uso de Custom Events:
Using Events - LiveDocs
Custom Events - LiveDocs
Flex/AS3 – Truques e Dicas #7 – Custom Event
Eventos personalizados no Flex
Passando parâmetros entre Pop-Up e Application no Flex
Eventos personalizados interagindo entre telas

quarta-feira, 15 de julho de 2009

Getters and Setters

Para quem vem de Java vai ser mais fácil se familarizar com Flex / ActionScript.
Por exemplo, getters e setters tem o mesmo conceito mas tem uma diferença grande.

No Java um método getter ou setter é um método como qualquer outro método onde o nome se convencionou que seja: get/setAtributo, onde a primeira letra do nome do atributo fica maiúscula:
Ex.:
private String nome;

public String getNome() {
return this.nome;
}

public function setNome(String value) {
this.nome = value;
}
Enquanto, que no Flex temos métodos especiais get e set o que torna o código mais intuitivo pois podemos fazer referência direta a propriedade como se esta fosse pública. Ex.:
private var _nome:String;

public function get nome():String {
return this._nome;
}

public function set nome(value:String):void {
this._nome = value;
}
E via código podemos usar:
var nome:String = obj.nome; // em vez de obj.getNome();
obj.nome = "Fabio"; // em vez de obj.setNome("Fabio");

terça-feira, 14 de julho de 2009

Action Script 3 para Programadores Java

Achei um artigo interessante para quem está iniciando, principalmente para quem estiver vindo do Java.
Dá noções básicas sobre AS3. Muito bom.

O link é este: http://www.infoq.com/br/articles/actionscript-java

sábado, 27 de junho de 2009

Novos Livros em Português

Até agora tínhamos somente o Adobe Flex Builder 3.0 - Conceitos e Exemplos de Daniel Pace Schmitz. Agora temos mais três:
Isto é muito bom para nossa comunidade Flex e também um sinal que o Flex está ganhando força no mercado brasileiro.

quarta-feira, 6 de maio de 2009

Método construtor - Singleton

Em AS não existe uma forma de criar um método construtor de uma classe como private para assim podermos usar o Design Pattern Singleton.

Métodos construtores só podem ser public sendo opcional a sua presença.

Se a sua classe herda de outra é uma boa prática fazer a chamada explícita ao método construtor da superclasse usando super(), mas caso você esqueça não tem problema, se o compilador não encontrar esta chamada, então ele irá colocar como primeiro comando do seu construtor.

Se você não criar um método construtor também não tem problema, pois o compilador cria um método construtor vazio colocando super() dentro.

Outra coisa interessante é que você pode usar o comando return no método construtor, desde que não retorne nenhum valor.

Mas se você precisar usar o Design Pattern Singleton você pode usar o seguinte código:

package mypackage {
public class ClassSingleton {
private static var instance:ClassSingleton;

public function ClassSingleton(enforcer:SingletonEnforcer) {
if (enforcer == null) {
throw new ReferenceError("Essa classe é Singleton. Utilize getInstance.");
}
}

public static function getInstance():ClassSingleton {
if (ClassSingleton.instance == null) {
ClassSingleton.instance = new ClassSingleton (new SingletonEnforcer());
}

return ClassSingleton.instance;
}
}
}

/** Classe utilitária para proibir o acesso ao construtor da classe Singleton. */
class SingletonEnforcer { }

domingo, 19 de abril de 2009

FormattedInput

Estou lançando um novo controle.
Inspirado no meu controle anterior NumericInput (tanto que depende deste) e do MaskedTextInput, criei o FormattedInput.

FormattedInput auxilia em campos que só aceitam números preenchidos com zeros a esquerda, tais como: cep, cnpj, cpf, telefone. Na classe há algumas constantes para as entradas mais comuns, mas a propriedade inputFormat permite informar estas ou outras.

Como no NumericInput deve-se usar a propriedade value no lugar de text. Isto foi necessário para evitar o erro de estouro de pilha, pois imagine, é modificado a propriedade text esta por sua vez precisa formatar ela mesma ficando assim num loop perpétuo. Acho mais adequado setar os valores diretamente na propriedade text, mas no momento ficou mais prático criar a propriedade value, quem sabe numa próxima versão. E mesmo assim a propriedade value retorna um Number o que talvez seja útil dependendo da forma que o valor será persistido.

A alteração da propriedade inputFormat em runtime provoca a reformatação do valor.

O código fonte com exemplo pode ser baixado aqui. O fonte também se encontra na seção de arquivos da Lista Flex-Brasil, só que é disponível somente para os membros da lista.

sábado, 18 de abril de 2009

Criação dinâmica de objetos

Uma coisa que acho muito legal é a criação dinâmica de objetos.

Bem como isso funciona:
1. Fazer o import das classes que serão utilizadas.
import flash.net.registerClassAlias;
import mx.core.UIComponent;
import mx.containers.TitleWindow;
import mx.controls.TextInput;
import views.CadCliente;

2. Registrar as classes que você irá usar. O compilador "precisa" saber quais classes precisam ser compiladas. Para isso é necessário criar uma instância do objeto com new ou com registerClassAlias:

registerClassAlias
("views.CadCliente", CadCliente); // herda de TitleWindow
registerClassAlias("mx.controls.TextInput", TextInput);

Registrando as classes no aquivo que tem a tag Applicattion irá fazer com que possa ser criado objetos de forma dinâmica em qualquer parte do sistema.

3. Criação dinâmica.
import flash.net.getClassByAlias;
import
flash.utils.getDefinitionByName;

private function criacaoDinamica():void {
// var clazz:Class = getDefinitionByName("views.CadCliente") as Class; ou
var clazz:Class = getClassByAlias("views.CadCliente");

var window:TitleWindow =
TitleWindow(PopUpManager.createPopUp(this, clazz, true));

var clazzTI
:Class = getClassByAlias("mx.controls.TextInput");
var instance:UIComponent = new clazzTI() as UIComponent;

window.addChild(instance);
}

Em acréscimo dois métodos interessantes:
flash.utils.getQualifiedClassName e flash.utils.getQualifiedSuperclassName.
Os dois recebem um object como parâmetro e retornam uma string com o nome completo (pacote + classe) da classe (
getQualifiedClassName) e da sua classe pai (getQualifiedSuperclassName).

quinta-feira, 16 de abril de 2009

Bloco Static

No Java existe o bloco static:

static {
}

O bloco static é como se fosse um init, é o primeiro código que será executado quando se fizer referência a classe, com new ou acessando algum método static. Dentro do método estático só pode ser acessado atributos e métodos também estáticos.

No AS3, se tem algo parecido:

public class Classe {
metodoStatic();
trace("class criada");

public static function metodoStatic():void { }
}

AS3 permite incluir no corpo de uma classe não somente declarações de atributos mas também comandos que serão executados somente uma vez. É executado primeiro a declaração de atributos e depois os comandos encontrados no corpo da classe. E estes comandos como no Java só podem acessar atributos e métodos também estáticos.

terça-feira, 14 de abril de 2009

Último dia do mês

Esta é simples mas bem útil.

Em muitas linguagens existe um construtor como Date(ano, mês, dia), então o mais prático é fazer o seguinte (código válido para AS3) para se obter o último dia do mês:


public function lastDay(source:Date):Date {
var retorno:Date = new Date(source.fullYear, source.month + 1, 1);
retorno.setDate(retorno.date - 1);

return retorno;
}

Mas lendo o post Working with Dates in AS3 do blog Amy's Flex Diary descobri uma forma mais enxuta:

public function lastDay(source:Date):Date {
return new Date(source.fullYear, source.month + 1, 0);
}

Estas duas formas evita o programador de fazer cálculos adicionais para saber se o ano é bissexto ou não.