terça-feira, 22 de junho de 2010

Flex e Java usando BlazeDS


Boas pessoal..
Em aplicações web feitas em Flex é muito comum o uso de uma camada intermediária que possa acessar o sistema ou uma base de dados, o que tenho visto pr aí é o uso do PHP como esta camada intermediária, eu mesmo uso em projetos atuais o PHP, mas em certa ocasião tive de usar o Java, pois a base era Informix, então assim como o AMFPHP faz é a ponte entre o Flex e o PHP, o BlazeDs faz entre o Flex e o Java.
Neste post daremos coordenadas mais exutas possível.
Será assim:
Daremos as instruções iniciais, a implementação ( ou modelo do código ) e um exemplo.
Então vamos lá.


Preparando o Ambiente:

• Instalar o TomCat (presente no pacote de instalação do NetBeans)
• Criar uma pasta do projeto na pasta [@tomcat/webapps/]
• Descompactar o blazeds.war na pasta [@tomcat/webapps/[projeto]/]
• Editar o arquivo [@tomcat/webapps/[projeto]/WEB-INF/flex/remoting-config.xml]
implementação:

<destination id="[id destination]">
    <properties><source>[package].[class]</source></properties>
</destination>
onde:
id destination
        Este id será enxergado pelo Flex no atributo [destination@RemoteObject]
package
        Nome do Pacote da classe no Lado JAVA
class
        Nome da Class no Lado JAVA
ex.:

<destination id="dest_id">
    <properties><source>Pjava.Valores</source></properties>
</destination>


Lado FLEX:

• Criar um novo projeto.
• Instanciar o objeto RemoteObject.
implementação:

<mx:RemoteObject id="[identificador]"
    endpoint="http://[servidor]:[porta]/[pasta do projeto]/messagebroker/amf"
    destination="[id destination]"
    showBusyCursor="true"
    fault="[caso falhar]"
    result="[caso sucesso]"/>
onde:
identificador        identificador do objeto RemoteObject
servidor
        nome ou IP do servidor
porta
        porta em que está o serviço do TomCat
id destination    →
    Este é o id da tag destination no arquivo:
@tomcat/webapps/[projeto]/WEB-INF/flex/remoting-config.xml
caso falhar
    →    O evento é disparado quando ocorre alguma falha na transação
caso sucesso
    →    O evento é disparado quando a transação é bem sucedida, a classe [event] trás o resultado no atributo [result].
implementação:    event.result
ex.:

<mx:RemoteObject id="rm"
    endpoint="http://localhost:8080/meuprojeto/messagebroker/amf"
    destination="dest_id"
    showBusyCursor="true"
    fault="Alert.show('Falha na transação')"
    result="{Alert.show(event.result.toString())}"/>
• Envocar o RemoteObject.
implementação:

<mx:[objeto] click="{ identificador.atributo@Java }"/>
onde:
objeto
    →    Objeto do Flex
identificador
    →    O ID do RemoteObject
atributo@Java
    →    Atributo, Método ou evento no Lado JAVA
ex.:

<mx:Button click="{rm.getValor()}"/>
• Compilar o projeto


Lado JAVA:

• Criar um novo projeto.
• Criar uma nova classe (esta classe é chamada pelo destination)
• Criar atributos, métodos ou eventos de acordo com a necessidade
implementação:

public String [atributo]    =    [valor];
    public String [método]() {
    return [valor];
}
onde:
atributo
    →    Nome do atributo (Este deve ser o nome chamado no objeto de envocação no Lado FLEX)
método
    →    Nome do método    (Este deve ser o nome chamado no objeto de envocação no Lado FLEX)
valor
    →    Valor que será retornado ao Flex
ex. de método:

public String getValor(){
    return "meu valor";
}
• Compilar o projeto


Ainda no Ambiente:

• Copiar o conteúdo da pasta [[projeto flex]/bin-debug/] para a pasta [@tomcat/webapps/[projeto]/]
• Copiar as os arquivos *.class do projeto JAVA para a pasta [@tomcat/webapps/[projeto]/WEB-INF/class/]


Executando:

• Acessar url: [http://[servidor]:[porta]/webapps/[projeto]/[flex].html]


Diagrama:

Muito bem pessoal, está aí mais um post, aproveitem.
Até o próximo...

Flex: Passando eventos entre Custom Components

Olá pessoal.
Estamos aí pra dar continuidade ao post de como comunicar eventos entre componentes customizados do Flex.

Vou deixar abaixo o ambiente padrão para iniciarmos o tutorial.

Apresentando uma situação:
Digamos que você tenha em seu projeto dois Custom Components, o CC1 ( um Slider e um Label ) e o outro, CC2, seria um teclado formado por 6 botões numéricos, um botão para o "Ok", um Label que exibe o valor do botão numérico pressionado e um botão para limpar o Label... ok..
Abaixo estão os dois Custom Components:




Implementação: Passando eventos
Este caso é um pouco menos comum, mas pode ser útil, então vamos lá.

Imagine que teríamos a necessidade de que quando o usuário passar o mouse sobre algum número do CC2 o Slider do CC1 tenha que ficar com a cor de fundo diferente e quando o mouse sair de sobre o número o Slider volte à cor de origem. Neste caso faremos com que os Custom Components se conversem diretamente.
Vamos chamar o CC2 de componente enviador de evento, se é que essa palavra existe..rs, e o CC1 de receptor de evento, pois já que o CC2 irá controlar a cor de fundo do Slider do CC1, podemos dizer que o CC2 envia e o CC1 recebe.

Vamos ver o código do Custom Components CC2:

Código CC2:


No código CC2 pegamos como exemplo somente um Botão, mas a idéia se aplica a qualquer objeto que quisermos.
Repare que no evento mouseOver do Botão será chamada a função "__envia_cor_fundo_slider_over ()" ( linha 34 ), essa função ( linhas 20 a 22 ) faz com que seja disparado um evento de nome "cor_fundo_slider_over", este evento pode ter qualquer nome, então procure dar nomes que sejam facilmente associados ao tipo de ação que está executando.  Quando esta função é executada a classe principal poderá "escutá-la" e após isso qualquer outra classe envolvida no projeto poderá validar se a classe principal "ouviu" o evento com o nome pré-definido e executar qualquer ação.

Vamos ver o código do CC1 que está apto a "ouvir" o que o componente CC2 está enviando.

Código CC1:


Da linha 12 a 16 temos declarada a função "__recebe__cor_fundo_slider_over ()", repare que adicionamos a função "addEventListener( NOME DO EVENTO, FUNÇÃO () { ... } )", esta função é a responsável por ficar verificando ou "ouvindo" o evento que a classe principal receberá, mas para chegarmos à classe principal precisamos adicional antes da função a classe "Application" e o método "application" como já explicamos no post anterior. Resumindo: caso o mouse passe por cima do Botão no CC2, este enviará para a classe principal um evento personalizado chamado neste exemplo de "cor_fundo_slider_over", por outro lado a função "addEventListener" do CC1 ficará verificando na classe principal se este evento chegou lá, acontecendo isso a função anônima será disparada e no nosso caso ela está mudando a cor de fundo do slider. Não esquecendo que a função "__recebe__cor_fundo_slider_over()" deve ser chamada no inicio do programa ( linhas 3 a 6 ).

Abaixo está o programa:



Aí está, espero que seja útil, até o próximo post.

quarta-feira, 16 de junho de 2010

Flex: Passando valores entre Custom Components

Olá pessoal, este é o meu segundo post, desta vez voltado à plataforma Flex da Adobe.
Vamos mostrar formas de comunicar dois componentes customizados, que hora trataremos como classe e horas como custom components.
A princípio veremos como passar valores de custom component para outro e em um segundo post iremos passar eventos.
Espero que gostem e seja útil.

O Flex é uma ferramenta muito eficiente e um dos vários motivos para isso é a grande quantidade de componentes já existentes, pois imagine se você tivesse de construir, por exemplo, um componente do tipo Slider, você teria que dedicar um tempo escrevendo este componente, mas este e outros vários componentes já estão incorporados no Flex SDK 3. Mesmo assim se você tiver uma necessidade muito específica, como por exemplo, de construir um Slider e um Label que mostre o valor do Slider, e tenha de usar esta combinação de componentes diversas vezes no projeto, seria tedioso ter que ficar montando esta estrutura todas as vezes em que ela fosse necessária, por isso temos à nossa disposição os MXML Components ou também chamados de Custom Components que são como que classes que podemos montar nossa estrutura uma única vez e usá-la a qualquer momento quantas vezes for preciso.

Bem, como o objetivo desse post é mostrar a comunicação entre esses componentes, vamos ao trabalho.

São dois os tipos de comunicação entre Custom Components que queremos abordar aqui:
Um tipo seria de passar valores de um para outro e vice-versa e o outro tipo seria de comunicar um evento.

Apresentando uma situação:
Digamos que você tenha em seu projeto dois Custom Components, o CC1 seria o do exemplo acima, ( um Slider e um Label ) e o outro, CC2, seria um teclado formado por 6 botões numéricos, um botão para o "Ok", um Label que exibe o valor do botão numérico pressionado e um botão para limpar o Label... ok..
Abaixo estão os dois Custom Components:


Exemplificando o primeiro tipo (Passando valores):
No cenário acima, quando você pressionar uma tecla numérica no CC2 e depois pressionar "Ok" o valor da tecla irá fazer com que o Slider lá do outro componente, o CC1, se mova para este tal valor e o Label o exiba.

Exemplificando o segundo tipo (Passando eventos):
Imagine que nesse mesmo projeto teríamos a necessidade de que quando o usuário passar o mouse sobre algum número do CC2 o Slider do CC1 tenha que ficar com a cor de fundo diferente e quando o mouse sair de sobre o número o Slider volte à cor de origem.
Obs.: Trataremos desse segundo tipo em um próximo post.

Temos, então, duas situações diferentes e formas diferentes de implementá-las, mas o projeto é o mesmo, então vamos montar o ambiente:


Crie um novo projeto no Flex chamado "com_custom_comp".
Logo de cara crie os componentes indicados em nosso exemplo.
Coloque os dois componentes em seu Stage como se fossem componentes nativos do Flex, simplesmente arratando-os.
Pronto, o ambiente está montado e agora podemos começar a codificar os tipos de comunicação.

Implementando o primeiro tipo (Passando valores):
O primeiro tipo, que é o de passar valor, é um tanto intuitivo e segue a lógica mais próxima da que estamos habituados a trabalhar, então vamos mostrar como se faz.

No com_custom_comp.mxml:


Repare que temos alguns elementos importantes no código acima:
 - A variável publica "valor" do tipo int ( linha10 ), servirá para receber o valor numérico do CC2, pois quando ela receber qualquer valor, este será espelhado imediatamente para o CC1, ou seja, ela é uma variável de ligação entre os dois Custom Components;
 - As TAGs "ns1:cc1" ( linha 16 ) e "ns1:cc2" (linha 20) são os Custom Components em questão.

No cc2.mxml:


No código acima, quando o usuário clicar em algum botão numérico ( linhas 24 a 29 ) o "TextInput" ( linha 23 ) é alterado, exibindo o valor correspondente, mas é quando o botão "OK" ( linha 32 ) é pressionado que acontece o envio do valor para o outro componente.
A função "__exportar_valor ()" ( linhas 8 a 11 ) manipula a variável "valor", porém ela está presente em outra classe, então como acessá-la?


A resposta vem a seguir.
Vejamos a estrutura hierárquica do nosso pequeno sistema:


Verificamos claramente na ilustração acima que temos 3 classes que na verdade são os arquivos ou os componentes:
 - main class com_custom_comp: Esta é a classe que abriga os outros dois Custom Components e a variável "valor".
 - class CC1: Podemos dizer que este Custom Component fica lendo a variável "valor", então qualquer alteração nesta variável é refletida no Custom Component CC1.
 - class CC2: Este Custom Component também tem uma relação com a variável "valor", mas apenas de escrita.
 - var valor: Esta variável foi declarada na class mãe e para que os dois Custom Components acessem-na é preciso um recurso.
Repare que no Custom Component CC2 existe uma chamada para a classe "Application" seguido do método "application" ( Application.application.valor ) que diz para o CC2 olhar para os atributos, métodos e eventos da classe mãe com_custom_comp e neste caso para a variável "valor".
Sendo assim, a função citada acima "__exportar_valor ()" diz para o CC2 olhar para a variável "valor" que está na classe mãe e atribui o valor do "TextInput" a ela. Então pense que a variável apenas recebeu um valor que veio do CC2, ok.

No cc1.mxml:


Agora sim é que tudo se complementa, pois o Slider, presente no CC1, está recebendo um valor de "Application.application.valor" ( linha 10 ) , isto é, da mesma forma que acontece com o caso do CC2, o CC1 consegue acessar a variável "valor" por causa das chamadas "Application.application".

Dêem uma olhada na aplicação em funcionamento:







No próximo post trataremos de como comunicar eventos, que é o segundo tipo citado acima.
Até mais.