Ultimas Entradas »
Ultimos Comentários »
Entradas Populares »

Flex deepLinking - Parametros browser

Escrito por Mário Santos em Maio 13, 2008 – 10:07 am

Ontem tive um pequeno problema a desenvolver parte de um aplicativo (o frontend para o meu sistema imobiliário) onde necessitava de saber onde estava a correr o aplicativo, bem como o caminho relativo do servidor, já que tinha que obter varios caminhos para fotografias onde esses caminhos poderiam variar. Ou seja, precisava de saber o caminho onde as minhas fotos se encontravam, já que se estivesse a correr apenas em, por exemplo www.msdevstudio.com/immo/frontend/ saberia exactamente onde encontrar as minhas fotos, que estariam no caminho absoluto www.msdevstudio.com/immo/frontend/imgs mas o problema seria se mudasse de servidor, as fotos poderia passar a estar em www.meuserverto.com/imgs e aí teria que programar o flex para ir procurar as fotos a este caminho… mas dizem voces, porque não usar apenas source=”imgs/imgExempo1.png” ? pelo simples motivo que necessito de juntar algumas fotos a um HTML text, bem como dar a possibilidade do user mudar a directoria das imagens e os caminhos relativos. (não encontrei outra solução para já…)

Bom, dei de caras com as propriedades deepLink, que podem ser obtidas atravéz do browserManager/URLUtil, por isso fiz um pequeno exemplo que podem usar nas vossas aplicações, copiando o contudo do arquivo que disponibilizo em baixo para a raiz da vossa aplicação, depois basta fazerem o import na vossa aplicação:

import com.msdevstudio.urlUtils;

São então disponibilizadas as seguintes funções:

getPort():String

getProtocol():String

getServer():String

getDoc():String

getTodo():String

getPath():String

onde para receberem os respectivos elementos devem usar:

   1: var util:urlUtils = new urlUtils();
   2: //tomando como exemplo o link: http://msdevstudio.com/immo/backend/backend.html
   3:
   4: //buscar nome do servidor:
   5: var nomeServidor:String = util.getServer();
   6: //devolve: msdevstudio.com
   7:
   8: //buscar protocolo
   9: var protocolo:String = util.getProtocol();
  10: //devolve http
  11:
  12: //buscar porta
  13: var porta:String = util.getPort();
  14:
  15: //buscar url completo
  16: var urlCompleto:String = util.getTodo();
  17: //devolve http://msdevstudio.com/immo/backend/backend.html
  18:
  19: //buscar caminho relativo 
  20: var caminho:String = util.getPath();
  21: //devolve http://msdevstudio.com/immo/backend/
  22:
  23: //buscar o nome do portador do swf
  24: var documento:String = util.getDoc();
  25: // devolve backend.html

Isto não é nada mais que um simples package que simplifica as coisas em aplicações medias/grandes e que em muitas variadas situações se torna muito util.

Podem fazer o download aqui.

fiz um package pelo simples motivo de ajudar a quem ler a perceber como um package funciona, bem como se podem tornar simples a utilização destes packages principalmente pela sua reutilização por outros programadores e outras aplicações. Podem ver o código comentado também.

Aguarda-se feedback.

pdf Este artigo está disponivel em pdf para download.


Tags: , , , , , , , , ,
Escrito em Action Script & MXML, Flex | 1 Comentário »

Flex - Criação de componentes em AS3;

Escrito por Mário Santos em Maio 6, 2008 – 10:03 am

Depois de ter aqui falado de como um componente é apresentado no stage, bem como todos os passos da sua criação, falo agora, em continuação com a documentação da adobe, de como se deve proceder à implementação de um componente, bem com os passos a executar na sua implementação.

Estes procedimentos não são todos obrigatórios, mas deve-se ter em conta as suas dependências. Passo então a citar a fonte original, mas em português e com um exemplo não testado.

Passos para criar um componente

Quando se implementa um componente, regra geral, fazemos o override (re-escrita) de determinado métodos do componente, definimos novas propriedades, disparamos/criaamos eventos e efectuamos quaisquer outras alterações/personalizações tendo em conta o objectivo do nosso componente na aplicação.

Para implementar um componente, devemos seguir a seguinte ordem:

1. Se necessário, criamos skins para o nosso componente;
2. Criamos um ficheiro "Action Script Class file" tendo a estrutura:

1: package meuComponente

2: {

3: //importar o que iremos usar no nosso componente.

4:import mx.core.UIComponent;

5:import mx.controls.Button;

6: import mx.controls.TextArea;

7: import flash.events.Event;

8: 

9: // definimos o nosso evento pessoal que usaremos em baixo

10: [Event(name="change", type="flash.events.Event")]

 

a) Extendemos uma das classes base, todos os componentes são baseados na class UI, se desejarmos criar um componente de raiz, mais complexo, devemos extender esta class, caso contrario se só desejarmos implementar/extender um componente simples como um botão, extendemos apenas esse componente.

1: //extender a class que desejamos

2: public class Exemplo extends UIComponent {

3: 

8: }

b)  Especificamos as propriedades/variáveis que o utilizador pode definir usando as propriedades ou a tag MXML;

1: private var textObj:TextArea;

2: private var modeObj:Button;   

3: private var _textLabel:String;

 
c) Incluir (embed) qualquer gráfico ou skin.

1: //usando skins de um swf.

2: [Embed(source="Modal2.swf", symbol="blueCircle")]

3: public var modeUpSkinName:Class;

4: 

5: //importando/incluido uma imagem

6: [Embed(source="img/img1.png")]7: public var imagem1:Class;

 

d) Implementar o construtor da class.

1: public function Exemplo() {

2: super();

3: }

 
e) Implementar o método UIComponent.createChildren().
Chamada na inicialização do componente, util para adicionar-mos um novo child, por exemplo os nossos componentes TextArea e Button declarados em cima:

1: override protected function createChildren():void {

2: super.createChildren();

3: 

4: // Criar e inicializar a nossa TextArea.

5: if (!textObj)

6: {

7: textObj = new TextArea();

8: textObj.explicitWidth = 80;

9: //podemos adicionar um evento:

10: textObj.addEventListener("change", handleChangeEvent);

11: addChild(textObj);

12: }

13: 

14: // Criar e inicializar o nosso Botão

15: if (!modeObj)

16: { modeObj = new Button();

17: modeObj.label = "Exemplo de Btn";

18: addChild(modeObj);

19: }

20: }

 
f) Implementar o método UIComponent.commitProperties().
Chamado pelo método invalidateProperties(); que actualiza quaisquer as propriedades do nosso componente:

1: override protected function commitProperties():void {

2: super.commitProperties();

3:

4: if (modObj && _textLabel.lenght>0) {

5: //usando o label, se existir, da nossa variavel _textLabel

6: modObj.label=_textLabel;

7: invalidateDisplayList();

8: }

9: }

 
g) Implementar o método UIComponent.measure().
Chamado para recalcular (ao ser alterado) o tamanho do nosso componente, bem como definirmos as posições dos nosso childs.

1: override protected function measure():void {

2: super.measure();

3: 

4: //o tamanho do nosso UIComponent vai depender do tamanho dos

5: //childs, por isso temos que calcular o tamanho deles pra poder

6: //definir correctamente o layout do nosso componente.

7: 

8: var buttonWidth:Number = modeObj.measuredWidth;

9: var buttonHeight:Number = modeObj.measuredHeight;

10: 

11: // O valor do comprimento, por defeito e minimo são igauis

12: // á measeuredWidth da nossa TextArea mais o measuredWidth

13: // do nosso botão

14: measuredWidth = measuredMinWidth =

15: textObj.measuredWidth + buttonWidth;

16:

17: // O mesmo se passa com a altura do nosso componente que será

18: // igual à measuredHeight da nossa textArea + measuredHeight do

19: // nosso botão.

20: measuredHeight = measuredMinHeight =

21: modeObj.measuredHeight, buttonHeight;

22: }

 
h) Implementar o método UIComponent.layoutChrome().
Podemos definir mais algumas propriedades do nosso layout:

1:protected override function layoutChrome(unscaledWidth:Number, unscaledHeight:Number):void {

2: super.layoutChrome(unscaledWidth, unscaledHeight);

3:

4: this.textObj.disabled = true;

5: }

i) Implementar o método UIComponent.updateDisplayList().
Chamado pelo método invalidateDisplayList(); para redefinir a nossa DisplayList (caso sejam alterados os tamanhos do nosso componente) :

1: override protected function updateDisplayList(unscaledWidth:Number,

2: unscaledHeight:Number):void {

3: super.updateDisplayList(unscaledWidth, unscaledHeight);

4: 

5: // subtraimos um pixel dos bordos e usamos uma

6: // margem de 3 pixeis à esquerda e direita

7: // 1+1+3+3 = 8;

8: var usableWidth:Number = unscaledWidth - 8;

9: 

10: // Fazemos o mesmo para o topo e fundo

11: var usableHeight:Number = unscaledHeight - 8;

12: 

13: //tamanhos da textArea e botão

14: //a textArea terá o tamanho máximo do nosso compoenente

15: var textWidth:Number = usableWidth;

16: //a altura, definimos a altura maxima, subtraindo apenas a

17: // altura do nosso botão, para este fique logo em baixo da nossa

18: // textArea.

19: var textHeight:Number = usableHeight-modeObj.height;

20: textObj.setActualSize(textWidth, textHeight);

21:

22: //o nosso botão terá todo o comprimento no nosso componente

23: modeObj.setActualSize(usableWidth, modeObj.height);

24: 

25: // Redefinirmos as posições dos nosso childs

26: textObj.move(4,4); //x=y=(margem=3 + bordo=1)= 4

27: //x=margem+bordo=4, y=height+ espaço de 5px entre eles

28: modeObj.move(4,textObj.height+5);

29:

30: // Desenhamos uma linha à volta do nosso componente a negro pra

31: //servir de bordo.

32: graphics.lineStyle(1, 0×000000, 1.0);

33: graphics.drawRect(0, 0, unscaledWidth, unscaledHeight);

34: }

j) Adicionar propriedades, métodos, styles, eventos e metadata.
adicionamos o resto das propriedades do nosso componente:

1: //funções para definir e retornar a variavel textLabel (getters/setters)2: //função set/define

3: public function set textLabel(texto:String):void {

4: //mudamos o texto

5: _textLabel = text;

6: //temos que forçar a actualização do texto no componente

7: invalidateProperties();

8: }

9: 

10: //função para devolver o nosso texto do botão.

11: public function get textLabel():String {

12: return modeObj.text;

13: }

14: 

15: // Função para lidar com o evento disparado por nós no child.

16: private function handleChangeEvent(eventObj:Event):void {

17: dispatchEvent(new Event("change"));

18: }

 
Não esquecer no final de fechar o nosso componente, iciniado pelo package meuComponente { :
1: }

 
3. Salve o ficheiro ActionScript ou distribua como biblioteca .swc.
 
Para usar este componente, usaríamos no caso de actionScript:

1: import meuComponente.Exemplo;

2: //Declarando o componente

3: var tempComp:Exemplo = new Exemplo();

4: //Adicionando ao um panel, por exemplo:

5: meuPainel.addChild(tempComp);

6: //definindo o lanel do nosso botão no componente:

7: tempComp.textLabel="BOTAO";

 
Este exemplo, não foi testado e devem ser tomados em conta alguns erros que possam acontecer a testar, mas em principio funcionará bem. Este exemplo é dos mais completos, já que implementa directamente um UIComponent, ou seja, cria um componente de raiz.
Caso seja distribuído num swc, o "Exemplo" estará disponível tanto no action script, como na janela "Components" em "Custom".
Este exemplo e artigo foi baseado na documentação disponíveis aqui, aqui e aqui (EN)
 
 
Espero que seja verdadeiramente util!
Um Abraço!
 
image
Este artigo está disponivel em pdf para download.

Tags: , , , , ,
Escrito em Action Script & MXML, Air, Flex | 2 Comentários »

Adobe Flex; Ciclo de inciciação de Componente.

Escrito por Mário Santos em Maio 2, 2008 – 7:53 am

Ao percorrer a documentação da Adobe, reparei num resumo bastante interessante que fala do ciclo de execução/criação de cada componente da nossa aplicação, é incrível como cada simples botão ao ser adicionado a um container tem uma dezena de procedimentos até que seja disparado o evento creationComplete. Para quem já criou/extendeu um componente via action script já sabe bem do que falo, mas mesmo assim coloco a explicação.

Vou falar apenas do processo de adicionar um botão como child a um container (Box) com

o simples código:

   1: // Criar uma box, um botão, definir o label e adicionar como child
   2: var boxContainer:Box = new Box();
   3: 
   4: var b:Button = new Button()
   5: 
   6: b.label = "Enviar";
   7: 
   8: boxContainer.addChild(b);

O flex, procederá da seguinte forma:

1. É chamado o componente construtor (new Box e depois new Button)

2. Chamado o setter (b.label=) e actualizado todo o componente ( muitas das vezes são chamados métodos de actualização para definirem todo o layout: invalidateProperties(), invalidateSize(), ou invalidateDisplayList() )

3. Adiciona como child (filho) do box. Aqui o flex faz a maior parte do trabalho, executando-se a  seguinte ordem:

4. Define a propriedade parent do componente para fazer referencia ao seu "container".

5. Calcula e define o estilo/"style" de todo o componente.

6. Dispara o evento preinitialize do componente.

7. Chama o método createChildren() do componente.

8. Chama os métodos invalidateProperties(), invalidateSize(),  e invalidateDisplayList() para obrigar a serem disparadas/chamadas os métodos commitProperties(), measure(), ou updateDisplayList() no próximo evento render. A única excepção a estes acontecimentos, é que o flex não chama o método measure()  quando o "user/programador" define a altura e largura do componente.

9. Dispara o evento initialize no componente. Nesta altura todos os childs (childrens) no componente são inicializados, mas o componente ainda não foi correctamente definido no seu tamanho, nem processado o seu layout. Este evento pode ser usado para definir /executar procedimentos extra no componente antes que seja completamente processado.

10. Dispara o evento childAdd no componente "pai" / "parent".

11. Dispara o evento initialize do seu componente "pai" / "parent".

12. Durante o próximo evento render o flex faz as seguinte acções:

  • - Chama o métodos pela seguinte ordem:
  • commitProperties();
  • measure();
  • layoutChrome();
  • updateDisplayList();
  • - Finalmente é disparado o evento updateComplete no componente.

13. O flex, depois deste processo ainda poderá disparar eventos de renderização ( render ) se os métodos commitProperties(), measure(), ou updateDisplayList() forem executados/chamados através dos métodos invalidateProperties(), invalidateSize(), ou invalidateDisplayList().

14. Depois do ultimo evento render ser chamado, o flex executa as seguintes acções:

  • - Coloca o componente visível ( .visible=true; ).
  • - Dispara o evento creationComplete no componente. O componente é dimensionado e processado para o layout. Este evento é apenas disparado uma única vez e só quando o componente é criado.
  • - Dispara o evento updateComplete no componente, este evento também é disparado quando são alteradas quaisquer definições do componente, como layout, posição, tamanho ou qualquer alteração das características visuais.

A maior parte do trabalho de configuração, definição, e renderização de um componente acontece que este é adicionado a um container ( método addChild() ), isto porque enquanto o componente não for adicionado a um container, o flex não consegue saber o seu tamanho, definir as propriedade "in-line"/"inheriting" ou desenha-lo no ecrã.

Perceber estes passos, é essencial para conhecer  as propriedades e as operações que são executadas a quando da criação de um componente. Ajuda-nos também a perceber melhor porque é que às vezes temos certos erros no nosso código bem como a entender o processo de criação de um componente, o que se torna muito útil para criar-mos ou/ou extender  o nosso próprio componente.

Artigo original aqui (EN)

Abraço.

image Este artigo está disponivel em pdf para download.


Tags: , , , , , , , , ,
Escrito em Action Script & MXML, Air, Design & Web Design, Flex | 4 Comentários »

Boas práticas de programação em Action Script

Escrito por Mário Santos em Março 12, 2008 – 9:13 am

Como todos sabemos (ou devíamos) a questão de organização e reaproveitamento do código é algo bastante importante para as nossas aplicações, não só em action script mas também em todas as linguagens de programação.

Neste caso falo de action script 3, onde por vezes cometemos bastantes erros desnecessários principalmente ao criar as ligações dos nossos scripts/componentes com outros ou com o “stage” principal.

O João Saleiro do riapt.org escreveu um artigo bastante interessante e muito bem exemplificado sobre como evitar erros de programação e começa por nos indicar um exemplo de “best practices” quanto acedemos a propriedades/funções de/a vários objectos / movie clips.

Alem de indicar os erros mais comuns, indica as causas e soluções muito bem documentadas com código e exemplos.

Aconselho a leitura atenta deste artigo a todos os programadores action script , aqui fica o link para o post original:

www.riapt.org - boas práticas

Abraço.


Tags: , , , , , , , , , , , , ,
Escrito em Action Script & MXML, Duvidas, Flash, Flex, Source Code, Tutoriais | Sem Comentários »