logo
  • Home
  • Acerca
  • Autores
  • Faq
  • Rede
  Twitter   Feed-me! RSS!
Dez 13

[Android] Instalando a MIUI ROM no Motorola Milestone 2

Escrito por Erko Bridee em 1, 2.0, 2009, 3.5, 3g, 4, 6, action, Adobe, Adobe Air, Air, Android, api, Aplicativos, app, AR, back, bar, BI, blog, break, C#, cache, class, Curso, custom, dados, demo, Desenvolvimento, developer, Dica, Dicas, Download, err, fonte, for, game, Google, html, ide, IE, if, image, int, iphone, jandersonfc, Links, lista, lite, loop, Mac, menu, mg, NaN, O, on, oop, PHP, problema, processo, prova, pt, RIA, Ria’s Geral, RoR, S+S, site, TAT, Touch, Tutoriais, Tutorial, tv, Twitter, UI, update, window, windows, zend @ 12 13th, 2011 | via http://blog.erkobridee.com | Sem comentários
Erko Bridee
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Depois de ver o Motorola Milestone 1 do @jandersonfc e do @horochovec rodando a MIUI ROM (Android) e ver que os respectivos aparelhos estavam impressionantemente r?pido, resolvi enfim entrar na onda e atualizar meu Motorola Milestone 2 para a MIUI ROM. Instalei (12/12/2011) a vers?o MIUI-1.12.02 a qual utilizar a vers?o Android 2.3.7 como base.

Site Oficial (vers?o em Ingl?s)

Para atualizar meu Motorola Milestone 2 para a MIUI ROM, tentei seguir o tutorial indicado pelo @plcosta, neste [link], mas confesso que depois de 3 tentativas frustradas desanimei, ent?o pedi uma ajuda para o @horochovec, para usar voltar a ROM original do Milestone 2 e recome?ar o processo de atualiza??o do zero. Finalmente tivemos a id?ia de olhar um tutorial de instala??o do CyanogenMod para o Milestone 2 [link], em resumo bastou seguir os passos indicados necesse tutorial que consegui realizar a instala??o da MIUI ROM no meu Milestone 2.

Realizei uma mescla dos 2 tutoriais para realizar a instala??o…

O que posso dizer, agora que estou usando a MIUI ROM?

Recomendo, quem instalar vai gostar muito.

Quer instalar a MIUI ROM tamb?m?

Caso queira mesmo, a seguir segue algumas instru??es conforme realizei a instala??o.

Aten??o: ? necess?rio lembrar que esse procedimento ? por sua conta e risco.

Obs.: com um pouco de aten??o, voc? tamb?m vai conseguir instalar a MIUI ROM no seu Milestone sem fazer nenhuma besteira.

Voc? tem o Motorola Milestone 1?

Mesmo n?o sendo o meu objetivo aqui, o @horochovec j? vez um [post] no blog dele que descreve os passos para a instala??o. (Sinceramente a instala??o no Milestone 1 me parece bem mais f?cil e r?pida que no Milestone 2 hehe)

N?o est? afim de apanhar como eu na instala??o no seu Milestone 2?

A seguir irei listar o passo a passo que realizei.

Obs.: no meu caso eu utilizo um Mac, ent?o tenha acess?vel um computador com Windows para te facilitar a vida. Se algo der errado n?o se desespere, ? s? voltar a ROM original do aparelho e recome?ar o procedimento para instala??o da nova ROM, para voltar esta ROM original ? que ser? necess?rio o Windows.

O que voc? vai precisar para realizar a instala??o da MIUI ROM

- Gingerbreak – para rootear o celular

- UPDATE_1.12.02_0.zip – MIUI ROM que utilizei e instalei no meu Milestone 2

- Bootmenu v0.8.6-v2.zip – arquivo do menu do boot para voc? conseguir selecionar e instalar a MIUI ROM

- Bootstrap – Droid 2 Bootstrap (Android Market) – necess?rio para acessar o bootmenu

- Rsd Lite – Aplicativo da Motorola para instalar SBF, serve para atualizar o Bootloader do aparelho e caso precise voltar a ROM original do aparelho, voc? ir? utilizar este aplicativo para realizar a tarefa. Lembrando que este aplicativo ? exclusivo e s? possui vers?o para MS. Windows.

Aten??o: sempre que voc? for executar o Rsd Lite para instalar uma SBF, tenho o m?ximo de cuidado, o procedimento deve ser executado e conclu?do 100%, este ? o ?nico procedimento que pode causar a perda irrevers?vel do aparelho.

- SBFs : Bootloader 70.13 e Vers?o original da ROM do Milestone 2 ( vers?o 2.2 Brazil, a primeira linha )

Tenha esses arquivos listados acima no seu computador, para facilitar sua vida =]

Procedimento para instalar a MIUI ROM no Motorola Milestone 2

Caso voc? queira ser cautelos@ e realizar um backup do seu celular, veja este [ link 1 - ROM original | 2 - aplicativos e dados ]. Eu particularmente n?o vi utilidade pr?tica nisto, pois ? tudo ou nada, queria a nova ROM no meu aparelho hehe.

Lembrando que os passos descritos a seguir foram os que eu utilizei na instala??o…

Sempre que for executar esse procedimento, fa?a com a bateria carregada.

Passos:

1 - Copie os arquivos: Gingerbreak.apk, UPDATE_1.12.01_0.zip, Bootmenu v0.8.6-v2.zip para o SD Card do aparelho

1.1 - Caso voc? tenha feito o download do Bootstrap.apk, copie este arquivo tamb?m para o SD Card

2 - Renomeie o arquivo UPDATE_1.12.01_0.zip para update.zip, este procedimento ? para facilitar o processo de instala??o.

3 - Verifique no aparelho, nas configura??es do Android a op??o Aplica??es(Programas) submenu, Desenvolvimento se as op??es, Fontes desconhecidas e Depura??o USB est?o ativas.

4 - Atrav?s do Gerenciador de arquivos localize o arquivo Gingerbreak.apk clique sobre ele e instale. Fa?a o mesmo para o Bootstrap, caso voc? tenha este.

4.1 – Caso tenha optado em n?o baixar este, acesse o Market do Android e instale por l? (Droid 2 Bootstrapper).

4.2 - Execute o aplicativo Gingerbreak, pois ? necess?rio rootear o aparelho para continuar a instala??o. A execu??o desse aplicativo ir? reinicar o aparelho, n?o se preocupe.

5 - Execute o Droid 2 Bootstrapper, neste aplicativo clique:

5.1 - Bootstrap Recovery

5.2 - Reboot Recovery

6 - Seu aparelho ser? reiniciado e exibir? um menu (em verde) com algumas op??es, onde o bot?o (+) do volume sobre, o (-) desce e o bot?o de tirar foto representa (ok/enter)

6.1 - Selecione: “install zip from sdcrad”

6.2 - Localize e selecione o arquivo: Bootmenu v0.8.6-v2.zip e (ok)

6.3 - Ap?s a instala??o, selecione a op??o do menu: “GO Back” (ok)

6.4 - Selecione a op??o: “Reboot System now” (ok)

7 - Seu aparelho ser? reiniciado novamente e exibir? um menu (azul), onde neste os comando para (ok/enter) ? o bot?o onde voc? liga o aparelho (power)

7.1 - Selecione: “Boot” (power)

7.2 - Selecione: “Set default: [boot Menu]“ (power)

7.3 - Selecione: “nomal” (power)

7.4 - Selecione: “Go Back” (power) 2x

7.5 - Selecione: “Recovery” (power)

7.6 - Selecione: “Custom Recovery” (power)

8 - Voc? ver? novas op??es no menu e uma imagem Android BootMenu, neste menu o comando para (ok/enter) ? o bot?o onde voc? liga o aparelho (power)

8.1 - Selecione: “Wipe data/Factory Reset” (power) Nesta op??o todos as informa??es na mem?ria embarcada do aparelho ser?o limpas.

8.2 - Selecione: “advanced” (power)

8.2.1 - Selecione: “Wipe Dalvik Cache” (power)

8.2.2 - Selecione: “Wipe Baterry Stats” (power)

8.2.3 - Volte ao menu anterior

8.3 - Necess?rio repetir o passo 8.1 - Selecione: “Wipe data/Factory Reset” (power)

8.4 - Selecione: “Apply update from sdcard” (power)

8.5 - Ap?s finalizar a instala??o, selecione a op??o: “reboot system now”

9 - Seu aparelho ir? iniciar e exibir o s?mbolo da motorola em vermelho, diferente a ROM default do MotoBlur, nesta etapa ? aguardar e esperar a MIUI ROM ser carregada. (Demorou uns 3 minutos ou 5 minutos at? entrar pela primeira vez)

Estou esperando a um bom tempo e n?o entrou, o que eu fa?o?

Bom caso voc? esteja em desespero vendo seu celular em um loop infinto, dizendo que est? carregando o Android e at? agora nada. N?o se desespere, eu passei por isso 3 vezes at? conseguir instalar a MIUI ROM.

Mantenha a calma.

Nessa situa??o voc? vai precisar do Rsd Lite, um computaor MS. Windows.

Como j? havia indicado para fazer download dos arquivos .sbf, neste momento ? que se faz uso deles.

Passos:

1 - Desligue o aparelho

2 - Ligue o aparelho segurando o bot?o power e a ceta para cima do teclado do Milestone 2

3 - Quando observar que a tela ligou, por?m est? preta, solte os bot?es

Aten??o: m?ximo cuidado nesse momento, mantenha o cabo USB sempre conectado, nunca pare o procedimento, esta etapa ? cr?tica e pode danificar o seu aparelho caso n?o seja executada corretamente.

4 - Verifique e certifique-se de que a vers?o do Bootloader ? a 70.13 (caso voc? nunca instalou nenhuma ROM deve ser)

4.1 - Caso n?o for a vers?o indicada, plugue o cabo usb no celular e no computador e na aplica??o Rsd Lite, selecione o arquivo .sbf referente ao bootloader, depois desligue e ligue novamente para acessar o bootloader.

4.2 - Estando na vers?o correta e com o aparelho ligado via usb, utilizando o Rsd Lite, selecione o arquivo .sbf referente a ROM original do aparelho.

5 - Terminando a instala??o, mantenha o aparelho conectado no computador at? o Android ser carregado totalmente, somente depois disso voc? poder? desconectar o cabo usb.

6 - Voc? est? com seu aparelho de volta ao estado de quando voc? comprou e tirou ele da caixa.

7 - Provavelmente voc? ter? que logar no MotoBlur, execute o seu login at? que acesse totalmente ao Android.

8 - Voltei ao passo 1 do procedimento de instala??o da ROM.

Aeee, acessou a tela da MIUI, ufa… hora de fazer o ajuste fino

Voc? perceber? que estar? com a MIUI em Ingl?s, mas isto n?o ? um problema, basta alterar o idioma para portugu?s.

- Altera o idioma para Portugu?s (Brasileiro) [link]

- A ilumina??o do teclado n?o vem habilitada inicialmente, para arrumar isto, veja este [link]

- Calibrar a bateria do aparelho para um melhor rendimento [link]

- A MIUI n?o vem com um teclado Swype, ent?o instalei: TouchPal Keyboard e o dicion?rio para Portugu?s Brasileiro

Um grande vil?o do consumo de bateria ? o 3G no aparelho que fica ativo 100% do tempo desde que este esteja habilitado, para resolver isso instalei o aplicativo APN Brasil Pro (Android Market), que possui um recurso que melhora o gerenciamento do 3G e ajuda consideravelmente a aumentar o tempo de vida da bateria do aparelho.

Deixo registrado aqui meus agredimentos a galera que me ajudou com dicas e links e informo que esses passos que descrevi foi uma mescla dos posts:

- @ajudandroid – MIUI VERS?O 1.11.18 “ATUALIZADA PARA VERS?O 1.12.02 04/12/2011

- Clube do Android – CyanogenMod 7 Android 2.3.5 para Milestone 2


Veja também:

  • Google Nexus Two
  • [ Adobe AIR ] Package Assistant Pro
  • Adobe AIR – Empacotador para iPhone OS + demos
  • [Android Game] Angry Birds : acessando níveis travados
  • Segundo comercial DROID da Verizon : stealth ataca EUA
Jul 5

Adobe @ the Museum 2

Escrito por Mauro Martins em .NET, 1, 2.0, 4, 6, Adobe, Adobe User Group, Air, Android, app, AR, AUG, BI, Blazeds, blog, break, C#, class, Desenvolvimento, Desenvolvimento RIA, development, err, event, Evento, Eventos, events, flash, Flash / Flex, flash builder, Flex, for, framework, Frameworks, image, int, Links e sugestões, map, Mate, mg, mobile, O, on, platform, produto, RIA, Ria’s Geral, S+S, site, Spring, tag, UI, User Group @ 07 5th, 2011 | via http://imauro.com/blog/ | Sem comentários
Mauro Martins
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

augPortoLogo Adobe @ the Museum 2

Olá a todos!

Serve este post para vos dar conhecimento do próximo evento da Adobe User Group Porto, o Adobe @ the Museum 2.

O evento vai ter lugar no Museu Soares dos Reis, no dia 16 de Julho, e tem como “estrela” internacional o Mihai Corlan da Adobe.

O Mihai é um Adobe Platform Evangelist para, Flex, AIR, BlazeDS… (podem ver o site dele em http://corlan.org/)

Aqui fica o alinhamento:

  • 10:00 Recepção
  • 10:30 Developing mobile apps for Android, iOS, and PlayBook with AIR and Flex – Mihai Corlan
  • 11:15 Break
  • 11:45 Frameworks de desenvolvimento RIA (Swiz, Mate, Parsley, Spring4AS, RobotLegs) – Rui Silva
  • 12:30 Almoço
  • 14:00 Hands-on: Introduction to mobile development for Android/iOS/PlayBook using Flash Builder, Flex, and AIR (part I) – Mihai Corlan
  • 14:45 Break
  • 15:00 Hands-on: Introduction to mobile development for Android/iOS/PlayBook using Flash Builder, Flex, and AIR (part II) – Mihai Corlan
  • 16:30 A anunciar
  • 17:15 Encerramento

No final ainda vamos sortear uma suite de produtos Adobe, e mais alguns souvenirs!

Se puderem passem a palavra a vossos amigos, colegas etc. e, se se quiserem registar, por favor, façam-no em http://augporto.stagehq.com/events/905

Vai ser uma oportunidade em grande e a não desperdiçar!



Jun 8

Java + JPA + Hibernate + DAO Genérico

Escrito por SamuelFacchinello em 1, 2.0, 3.5, 4, 6, action, Adobe, Adobe Flex, AR, back, Banco de Dados, blog, Blogs, break, busca, C#, catch, class, classe, dados, err, erro, exemplo, finally, Flex, for, framework, Google, Hibernate, html, IE, if, int, Java, JPA, lista, mg, O, on, print, procura, Projetos, pt, reference, RIA, Ria’s Geral, S+S, Spring, string, super(), TAT, Teste, try, UI, update, validação @ 06 8th, 2011 | via http://desenvolvendoemflex.blogspot.com/ | Sem comentários
SamuelFacchinello
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Olá, hoje vou mostrar como fazer um DAO Genérico no Java (contendo SaveOrUpdate, Remove, FindAll, FindByID) que pode ser usado por todos os DAOs. Facilitando a criação de novos projetos, podendo ser usado com a integração com o Adobe Flex através do RemoteObject.

Isto é para quem não quer usar nenhuma espécie de Framework (ex: Spring, que faz isso de uma forma mais genérica).

Primeiramente criei minha classe contendo todos os métodos (save, update, delete, find), para minha classe ficar “genérica” ao invés de receber as entidades específicas, recebe Object (pode passar as Entidades que o java consegue reconhecer). Após criar esta classe contendo os métodos, é só criar os DAOs extendendo da classe genérica, com isso já terá todos os métodos implementados. Podendo fazer validações específicas para cada DAO.

Vamos a prática:

Este é minha classe genérica contendo todos os métodos.
GenericDAO.java
Leia mais…

Mai 28

TextArea com atalho para Desfazer e Refazer

Escrito por SamuelFacchinello em 1, 2.0, 4, 6, Adobe, Adobe Flex, AR, as2, BI, Bindable, blog, Blogs, botão, break, C#, case, class, código, código fonte, collection, Componente, control, Controls, Download, event, EventListener, Evento, events, flash, Flex, fonte, for, function, gestão, git, Google, html, IE, if, int, mg, O, on, padrão, RIA, Ria’s Geral, S+S, site, string, super(), Tema, tv, UI, utils @ 05 28th, 2011 | via http://desenvolvendoemflex.blogspot.com/ | Sem comentários
SamuelFacchinello
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Por padrão o componente TextArea do Flex não possui função de desfazer e refazer, com isso resolvi implementar estas duas funções.

Para testar é só digitar um texto, e pressionar Ctrl+Z para desfazer e Ctrl+Y para refazer.

*download do fonte: botão direito “View Source”

Código Fonte:

/*############################################################*/
/*                                                            */
/*   Powered by: Samuel Facchinello                           */
/*   http://desenvolvendoemflex.blogspot.com/                 */
/*                                                            */
/*############################################################*/
package com.blogspot.desenvolvendoemflex.utils
    import flash.events.Event;
    import flash.events.KeyboardEvent;

    import mx.collections.ArrayCollection;
    import mx.controls.Alert;
    import mx.controls.TextArea;

    /**
     *
     * @author SAMUEL FACCHINELLO
     * @site http://desenvolvendoemflex.blogspot.com/
     */
    public class TextAreaWithUndo extends TextArea 

        /**
         * Variable of control position Undo or Redo
         * */
        [Bindable]
        private var _position:int = -1;

        public function get position():int
            return _position;

        /**
         * Variable that stores all typed letters
         * */
        [Bindable]
        private var _array:ArrayCollection = new ArrayCollection();

        public function get array():ArrayCollection
            return _array;

        /**
         * Constructor
         *
         */
        public function TextAreaWithUndo()
            super();
            //add value default
            addValue("");

            //add Event on KeyDown
            addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);

        /**
         * Function with KeyDown
         * @param eventObj: KeyboardEvent
         *
         */
        private function myKeyDown(eventObj:KeyboardEvent):void
            // Was Ctrl key pressed?
            if (eventObj.ctrlKey)
                var valueReturn:String = null;

                switch (eventObj.keyCode) 

                    case 90: // Was Ctrl-Z pressed?
                        valueReturn = returnPrevisionValue();
                        break;

                    case 89: // Was Ctrl-Y pressed?
                        valueReturn = returnNextValue();
                        break;

                    default:
                        break;

                //if return exist
                if (valueReturn!=null)
                    //set text with return functions
                    text = valueReturn;

                    //select last _position in TextArea
                    setSelection(text.length, text.length);

            } else
                //only adds to the list if any of these characters.
                //list from here: http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000520.html
                if ((eventObj.keyCode>=65&&eventObj.keyCode<=90)
            }
        }

        /**
         * Function that adds the letters in the array
         * @param value: propertie "text" of TextArea
         *
         */
        private function addValue(value:String):void
            //it was press Ctrl + Z ever, and was entered some value, clears the values ??of the position in which this forward
            if (_array.length>0&&_array.length-1>_position)
                for (var i:int = _array.length-1; i>_position; i--)
                    _array.removeItemAt(i);

            }

            //if the value is being added is equal to the last added, not added!
            if (_array.length>0)
                if (value==_array.getItemAt(_array.length-1))
                    return;

            }

            _array.addItem(value);
            _position++;
        }

        /**
         * triggered when press Ctrl + Y
         * @return : Returns the next value from the list according to position
         *
         */
        private function returnNextValue():String
            if (_position+1>=0&&_position+1<_array.length)
                _position++;
                return _array.getItemAt(_position) as String;

            return null;
        }

        /**
         * triggered when press Ctrl + Z
         * @return : Returns the Prevision value from the list according to position
         *
         */
        private function returnPrevisionValue():String
            if (_position-1>=0)
                _position--;
                return _array.getItemAt(_position) as String;

            return null;
        }
    }
}

Adicionei este componente ao Google Code, pode ser visto aqui: http://code.google.com/p/textarea-with-undo/

Qualquer elogio, dúvida, sugestão ou melhoria para o componente, deixe um comentário!!

Abraço, até a próxima.

*Tradução para o inglês com o Google Translate. :)

Mai 19

Enriquecendo sua aplicação flex utilizado eventos do teclado

Escrito por Willian Mano em .NET, 1, 2.0, 4, app, AR, arte, Atalhos, BI, blog, break, browser, C#, camp, case, class, classe, código, código fonte, err, erro, event, Evento, Eventos, exemplo, flash builder, Flex, fonte, for, git, html, IE, if, int, internet, map, mg, O, on, redeRIA, rest, RIA, Ria’s Geral, Rich Internet Application, S+S, screen, Screencast, screencasts, Scroll, site, state, TAT, Tema, Tutorial, Twitter, UI, Ved, XP @ 05 19th, 2011 | via http://blog.willianmano.eti.br/ | Sem comentários
Willian Mano
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Como a maioria deve saber o significado de RIA é rich internet applications. Há muito tempo atrás, assistindo a um dos screencasts do? Vedovelli, ele falou que o flex é muito rico e que você pode melhorar a experiência dos usuários trabalhando os pequenos detalhes da aplicação. Coisas como limpar os campos e mudança de foco são primordiais para deixar suas aplicações mais intuitivas e fáceis de serem usadas.

Baseado nisso eu passei a prestar um pouco mais de atenção nesses detalhes e uma das coisas que veio ? cabeça foi os eventos de teclado. Claro eu não poderia de deixar de citar meu amigo? @brunoaraujo_id que foi o primeiro que eu vi a manipular esse tipo de evento e quem também me mostrou um exemplo no qual vou mostrar aqui.

Historinhas ? parte, vamos ao que interessa.

Nesse tutorial eu irei (tentarei) explicar como trabalhar com eventos de teclado e também como eles podem ser úteis na sua aplicação.

Primeiro vamos a um simples exemplo para que possamos observar um pouco melhor a classe KeyboardEvent.

Seu browser não suporta iframes.

No exemplo acima tem duas caixas de texto, quando você digita algo na primeira caixa de texto ele exibe na caixa de baixo as propriedades do evento. Nesse primeiro passo nós iremos observar apenas o? charCode e o? keyCode.

  • charCode: é o código do caractere, ele obedece a tabela ASCII e você pode pegar o valor de cada caractere? aqui. Lembrando que cada caractere tem seu código, ou seja, o a minúsculo é diferente do A MAIÚCULO.
  • keyCode: é o código numérico que corresponde ao valor da tecla no teclado. Ele pode variar conforme sistema operacional e dispositivo.

O mapeamento desses eventos é bem simples você deve apenas verificar qual a tecla pressionada e apartir dai executar alguma ação. Exemplo.

switch(event.keyCode) 

  //Quando o usuário apertar o esc
  case 27:
    //Executa alguma ação
  break;
  //Quando o usuário apertar o enter
  case 13:
    //Executa alguma ação
  break;

Bom, já sabemos qual evento iremos trabalhar e como pegar o código de uma tecla apertada, mas em que isso será útil? O próximo evento ilustra isso perfeitamente.

No exemplo acima eu estou mapeando os eventos do enter e do esc.

Quando o usuário está no state de login e pressiona enter ele verifica se o campo está vazio, se estiver mostrará uma mensagem de erro, caso contrário ele passará para o próximo state. Se o usuário pressionar esc o campo será limpo.

No state de senha ao pressionar esc ele também verifica se o campo está vazio, se estiver ele vai volta para o state de usuário, caso contrário ele irá limpar o campo. Se o usuário apertar enter ele irá dar uma alert avisando que naquele momento seria a hora de fazer o login.

Bom, mais explicações pelo código fonte, ele está bem simples de fácil compreensão.

Você pode também criar atalhos em seu aplicativo, pode por exemplo, fazer com que um ctrl+n deixe o texto em negrito.

Vamos a uma rápida passada sobre isso.

Volte para o primeiro exemplo e pressione ctrl + i.

O resultado do evento será:

[KeyboardEvent type="keyDown" bubbles=true cancelable=false eventPhase=3 charCode=105 keyCode=73 keyLocation=0 ctrlKey=true altKey=false shiftKey=false]

Notem que agora o ctrlKey tem o valor true. Usando no seu código você verifica se ele é true e depois verifica o código da tecla para criar as combinações de atalhos. Agora é só usar a criatividade.

Espero que essas informações tenham sido úteis para vocês.

Abraço e até a próxima.

Post to Twitter

Abr 26

Download de arquivo com Servlet e Flex

Escrito por Cognitiva Soluções em 1, 4, 6, Access, AR, blog, Blogs, break, business, catch, class, código, Curso, Download, err, exemplo, finally, Flex, for, function, Google, html, ide, IE, if, image, int, Java, mg, O, on, override, print, produto, pt, RIA, Ria’s Geral, string, TAT, try, UI, vs @ 04 26th, 2011 | via http://blog.cognitivasolucoes.com | Sem comentários
Cognitiva Soluções
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Segue um exemplo de como desenvolver um Servlet para download de arquivos realizando a integração com Flex.

Vamos ao Servlet:

package com.xxx.business.services;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.agriness.produto31.business.db.entities.Usuario;
import com.agriness.produto31.business.dto.Arquivo;
import com.agriness.produto31.commons.AccessProperties;
import com.agriness.produto31.core.exception.BusinessException;
import com.agriness.produto31.recurso310003.business.services.ArquivoDownload;

public class ServletDownloadFile extends HttpServlet {

 private static final long serialVersionUID = -1783732558472851554L;

 @Override
 @SuppressWarnings("unchecked")
 protected void service(final HttpServletRequest request,
   final HttpServletResponse response) throws ServletException,
   IOException {

  ArquivoDownload arqDown = new ArquivoDownload();
  Arquivo arq = new Arquivo();
  arq.setNome(request.getParameter("nome"));
  arq.setExtensao(request.getParameter("extensao"));
  arqDown.setArquivo(arq);
  arqDown.setCaminho("/download/");

  PrintWriter printwriter = response.getWriter();

  if (arqDown.getArquivo().getNome().length() == 0) {
   response.setContentType("text/html");
   printwriter.println("Nome do arquivo inválido");
   printwriter.flush();
   printwriter.close();
   return;
  }
  if (arqDown.getCaminho() == null) {
   response.setContentType("text/html");
   printwriter.println("Caminho do arquivo inválido");
   printwriter.flush();
   printwriter.close();
   return;
  }
  File file = new File(arqDown.getCaminho()
    + arqDown.getArquivo().getNome());
  if (file == null) {
   response.setContentType("text/html");
   printwriter.println("Arquivo não pode ser lido");
   printwriter.flush();
   printwriter.close();
   return;
  }

  if (!file.exists() || !file.canRead() || file.isDirectory()) {
   response.setContentType("text/html");

   if (!file.exists())
    printwriter.println("Arquivo inexistente");
   else if (file.isDirectory())
    printwriter.println("O arquivo é um diretório");
   else
    printwriter.println("Arquivo não pode ser lido");

   printwriter.flush();
   printwriter.close();
   return;
  }

  response.setHeader("Content-Disposition", "attachment; filename = "
    + arqDown.getArquivo().getNome());
  response.setContentType("octet-stream");

  int BUFF_SIZE = 1024;
  byte[] buffer = new byte[BUFF_SIZE];
  response.setContentLength((int) file.length());
  FileInputStream fis = new FileInputStream(file);
  OutputStream os = response.getOutputStream();

  int byteCount = 0;
  try {
   do {
    byteCount = fis.read(buffer);
    if (byteCount == -1)
     break;
    os.write(buffer, 0, byteCount);
    os.flush();
   } while (true);
  } catch (Exception excp) {
   excp.printStackTrace();
  } finally {
   os.close();
   fis.close();
  }

 }
}

Segue o código Flex:

public function executaDownloadFromUrl( url:String ):void{
   if( url == null ){
    return;
   }
   var u:URLRequest  = new URLRequest(url);
   navigateToURL(u);
  }

Monte a url conforme os atributos definidos no Servlet.
ex: http://meudominio.com/Servlet/?nome=nomeArquivo&extensao=.pdf

Abr 13

Silverlight 5 Beta disponível para download

Escrito por Kelps Sousa em .NET, 1, 2.0, 3.5, 4, 6, AR, Asp.Net, Beta, BI, Blend, blog, Blogs, break, C#, Desenvolvedor, Desenvolvimento, developer, Download, expression, Expression Blend, for, Google, IE, Mac, map, mg, Microsoft, MIX, mudanças, News, O, on, Review, Ria’s Geral, runtime, S+S, SDK, Service Pack, servidor, silverlight, tool, UI, Ved, Visual Studio, Visual Studio 2010, web, window, windows, XP @ 04 13th, 2011 | via http://kelps-sousa.blogspot.com/ | Sem comentários
Kelps Sousa
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

No MIX11, Scott Guthrie anunciou a disponibilização da versão beta do Silverlight 5 para download. Abaixo estão alguns link para os downloads relacionados a essa versão beta:

  • Visual Studio 2010 SP1 ou Visual Web Developer Express 2010 SP1 (é necessário ter o Service Pack 1 do Visual Studio para poder usar o Silverlight 5)
  • Silverlight 5 Tools for Visual Studio
  • Expression Blend Preview for Silverlight 5
  • Silverlight 5 SDK CHM
  • Runtime de desenvolvimento: Windows ed Mac – não é necessário se você instalar o tools. Só é necessário se for testar aplicações feitas em Silverlight 5 em computadores sem o tools do SL5 instalado.
  • Silverlight 5 SDK – para servidores de build. O tools já instala o sdk no computador do desenvolvedor
  • Documento de mudanças (breaking changes)



Mar 7

TextArea com Linhas.

Escrito por Felipe Borella em 1, 2009, 4, 6, Adobe, app, AR, back, bar, Blend, blog, Blogs, boolean, break, chrome, class, classe, classes, Componente, components, control, err, event, EventListener, events, exemplo, flash, Flex, fonts, for, function, gc, html, ide, IE, if, int, internet, label, layout, library, MXML, NaN, Number, O, on, override, pt, Ria’s Geral, Scroll, spark, state, string, strings, Stroke, TAT, UI, UML, update, XML, XP @ 03 7th, 2011 | via http://www.fborella.com.br/blog/ | Sem comentários
Felipe Borella
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Daeee galera!
Esse port é para mostra um Skin bacana que catei na internet.
Original em http://flexdevtips.blogspot.com/2010/07/spark-textarea-with-line-numbers.html

Vamos ao Skin:

xml version="1.0" encoding="utf-8"?>
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
			 xmlns:s="library://ns.adobe.com/flex/spark"
			 xmlns:mx="library://ns.adobe.com/flex/mx"
			 xmlns:fb="http://ns.adobe.com/flashbuilder/2009"
			 creationComplete="created(event)"
			 alpha.disabled="0.5"
			 blendMode="normal">
?
	<fx:Metadata>
		[CDATA[
		[HostComponent("spark.components.TextArea")]
		]]>
	fx:Metadata>
?
	<fx:Script fb:purpose="styling">
		private var lineBreakChanged:Boolean;
?
		private var paddingChanged:Boolean;
?
		private var verticalAlignChanged:Boolean;
?
		/* Define the skin elements that should not be colorized.
		For text area, the skin itself is colorized but the individual parts are not. */
		static private const exclusions:Array = ["background", "scroller"];
?
		/**
		 * @private
		 */
		override public function get colorizeExclusions():Array {
			return exclusions;
		}
?
		/* Define the content fill items that should be colored by the "contentBackgroundColor" style. */
		static private const contentFill:Array = ["bgFill"];
?
		/**
		 *  @private
		 */
		override public function get contentItems():Array {
			return contentFill
		}
		;
?
		/**
		 *  @private
		 */
		override protected function commitProperties():void {
			super.commitProperties();
?
			if (lineBreakChanged) {
				updateStringStyle("lineBreak");
				lineBreakChanged = false;
?
				if (textDisplay != null) {
					if (getStyle("lineBreak") == "explicit") {
						if (textDisplay.percentWidth == 100) {
							textDisplay.width = NaN;
						}
					} else if (textDisplay.percentWidth != 100) {
						textDisplay.percentWidth = 100;
					}
				}
			}
			if (paddingChanged) {
				updatePadding();
				paddingChanged = false;
			}
			if (verticalAlignChanged) {
				updateStringStyle("verticalAlign");
				verticalAlignChanged = false;
			}
		}
?
		/**
		 * @private
		 */
		override protected function initializationComplete():void {
			useChromeColor = true;
			super.initializationComplete();
		}
?
		/**
		 *  @private
		 */
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
			if (getStyle("borderVisible") == true) {
				border.visible = true;
				shadow.visible = true;
				background.left = background.top = background.right = background.bottom = 1;
				scroller.left = scroller.top = scroller.right = scroller.bottom = 1;
			} else {
				border.visible = false;
				shadow.visible = false;
				background.left = background.top = background.right = background.bottom = 0;
				scroller.left = scroller.top = scroller.right = scroller.bottom = 0;
			}
?
			borderStroke.color = getStyle("borderColor");
			borderStroke.alpha = getStyle("borderAlpha");
?
			super.updateDisplayList(unscaledWidth, unscaledHeight);
		}
?
		/**
		 *  @private
		 */
		private function updatePadding():void {
			if (!textDisplay)
				return;
?
			// Push padding styles into the textDisplay
			var padding:Number;
?
			padding = getStyle("paddingLeft");
			if (textDisplay.getStyle("paddingLeft") != padding)
				textDisplay.setStyle("paddingLeft", padding);
?
			padding = getStyle("paddingTop");
			if (textDisplay.getStyle("paddingTop") != padding)
				textDisplay.setStyle("paddingTop", padding);
?
			padding = getStyle("paddingRight");
			if (textDisplay.getStyle("paddingRight") != padding)
				textDisplay.setStyle("paddingRight", padding);
?
			padding = getStyle("paddingBottom");
			if (textDisplay.getStyle("paddingBottom") != padding)
				textDisplay.setStyle("paddingBottom", padding);
		}
?
		/**
		 *  @private
		 */
		private function updateStringStyle(styleName:String):void {
			if (!textDisplay)
				return;
?
			// Push style into the textDisplay
			var style:String;
?
			style = getStyle(styleName);
			if (textDisplay.getStyle(styleName) != style) {
				textDisplay.setStyle(styleName, style);
			}
		}
?
		/**
		 *  @private
		 */
		override public function styleChanged(styleProp:String):void {
			var allStyles:Boolean = !styleProp || styleProp == "styleName";
?
			super.styleChanged(styleProp);
?
			if (allStyles || styleProp.indexOf("lineBreak") == 0) {
				lineBreakChanged = true;
				invalidateProperties();
			}
			if (allStyles || styleProp.indexOf("padding") == 0) {
				paddingChanged = true;
				invalidateProperties();
			}
			if (allStyles || styleProp.indexOf("verticalAlign") == 0) {
				verticalAlignChanged = true;
				invalidateProperties();
			}
		}
	fx:Script>
?
	<fx:Script>
		[CDATA[
			import mx.events.FlexEvent;
?
			/**
			 * @private
			 */
			private static const focusExclusions:Array = ["textDisplay"];
?
			/**
			 *  @private
			 */
			override public function get focusSkinExclusions():Array {
				return focusExclusions;
			}
?
			protected function created(event:FlexEvent):void {
				updateLineNumbers(event);
				hostComponent.addEventListener(FlexEvent.UPDATE_COMPLETE, updateLineNumbers, false, 0, true);
			}
?
			private var _lines:int = 0;
?
			private function updateLineNumbers(event:Event):void {
				var lines:int = textDisplay.mx_internal::textContainerManager.numLines;
				if (lines != _lines) {
					var old:int = _lines;
					this._lines = lines;
					var diff:int = lines - old;
					var linesString:String;
					var i:int;
					if (diff > 0) {
						linesString = lineNumbersLabel.text;
						for (i = old + 1; i <= _lines; i++) {
							if (i > 1) {
								linesString += "n";
							}
							linesString += i.toString(10);
						}
					} else {
						linesString = "";
						for (i = 1; i <= _lines; i++) {
							if (i > 1) {
								linesString += "n";
							}
							linesString += i.toString(10);
						}
					}
					lineNumbersLabel.text = linesString;
				}
			}
		]]>
	fx:Script>
?
	<s:states>
		<s:State name="normal"/>
		<s:State name="disabled"/>
	s:states>
?
	
	
	<s:Rect id="border"
			bottom="0"
			left="0"
			right="0"
			top="0">
		<s:stroke>
			
			<s:SolidColorStroke id="borderStroke"
								weight="1"/>
		s:stroke>
	s:Rect>
?
	
	
	
		
			
			
		
	
?
	
	
	
		
			
		
	
?
	
	
		
			
				
			
			
			
				
					
				
			
			
				
					
				
			
		
?
		
			
			
		
	
?

E ao Uso do mesmo no componente

xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx" width="100%" height="100%">
	<fx:Declarations>
?
	fx:Declarations>
?
	<s:TextArea width="400" height="200" skinClass="br.com.fborella.SkinTextArea">
	s:TextArea>
s:Application>

Lembre-se de colocar o arquivo no seu pacore e ajustar o mesmo no skinClass

Exemplo:

Abraço

Felipe

Jan 7

Dica Flex – Utilizando o padrão Typesafe Enum no ActionScript 3.0

Escrito por Pablo Souza em 1, 2009, 4, 6, action, Actionscript, ActionScript 3, Adobe, app, AR, arte, BI, blog, boolean, break, case, class, classe, classes, código, demo, Dica, Download, err, erro, error, event, events, Excel, exemplo, Flex, for, function, handle, html, ide, IE, if, image, Java, library, Livro, MXML, O, on, Oracle, padrão, problema, pt, RIA, Ria’s Geral, RoR, Segurança, spark, state, string, TAT, Teste, UAU, UI, utf8, XML @ 01 7th, 2011 | via http://rectius.com.br/blog | Sem comentários
Pablo Souza
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Um das grandes passagens do livro Code Complete é sem dúvidas aquela que diz: “se uma linguagem não suporta nativamente uma determinada implementação, você deve então programar ‘para a linguagem’ e não ‘na linguagem’ “. O exemplo que o livro apresenta para essas limitações é justamente com relação ao Typesafe Enum, nossa dica Flex de hoje.

Os Enums são muito utilizados para evitar redundância de código e garantir o máximo de segurança nas aplicações. Além de serem excelentes objetos para se trabalhar com estados e tipos, eles também são parte essencial quando trabalhamos com o padrão de projeto State. Ele é muito utilizado também para limitar as opções de argumentos para determinados métodos. O problema é que diferente do Java 5 ou do ActionScript 2, o ActionScript 3 não suporta Enums e não permite usar o modificador privado no construtor das classes.

Suponha que temos um método que retorna a URL de uma imagem em 3 diferentes tamanhos: Pequeno, médio e grande. Para retornar o caminho dessa imagem passamos como argumento do método qual o tamanho que esperamos. Sem utilizar o Typesafe Enum poderíamos fazer conforme código abaixo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx"
               initialize="application1_initializeHandler(event)">

    <fx:Script>
        <![CDATA[
            import mx.events.FlexEvent;

            private static const PEQUENO:String     = "pequeno";
            private static const MEDIO:String     = "medio";
            private static const GRANDE:String   = "grande";

            protected function application1_initializeHandler(event:FlexEvent):void
            {
                trace( retornaCaminhoImagem("texto qualquer") );
            }

            private function retornaCaminhoImagem(tamanho:String):String
            {
                var caminho:String;
                switch(tamanho)
                {
                    case PEQUENO:
                    {
                        caminho = "http://www.suaurl.com/imagem_pequena.jpg";
                        break;
                    }
                    case MEDIO:
                    {
                        caminho = "http://www.suaurl.com/imagem_media.jpg";
                        break;
                    }
                    case GRANDE:
                    {
                        caminho = "http://www.suaurl.com/imagem_grande.jpg";
                        break;
                    }
                    default:
                    {
                        caminho = "[ERRO]";
                    }
                }

                return caminho;
            }

        ]]>
    </fx:Script>

</s:Application>

O problema no código acima é que podemos passar como argumento do método “retornaCaminhoImagem()” qualquer string:

1
trace( retornaCaminhoImagem("texto qualquer") );

Para resolvermos o problema acima vamos criar uma classe que implementa o padrão Typesafe Enum:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package enum
{
    public class ImageSizeEnum
    {

        public static const PEQUENO:ImageSizeEnum   = new ImageSizeEnum("pequeno");
        public static const MEDIO:ImageSizeEnum     = new ImageSizeEnum("medio");
        public static const GRANDE:ImageSizeEnum    = new ImageSizeEnum("grande");

        private var _tamanho:String;

        private static var _instance:Boolean = false;

        // Bloco estático
        {
            _instance = true;
        }

        public function ImageSizeEnum(tamanho:String)
        {
            if(_instance)
            {
                throw new Error("Você não pode instanciar um Typesafe Enum");
            }
            _tamanho = tamanho;
        }

        public function toString():String
        {
            return this._tamanho;
        }
    }
}

Repare no bloco estático que criamos, ele será excutado assim que a classe for carregada na memória, portanto antes do construtor da classe ser chamado e depois que todos os membros estáticos forem criados.

Agora crie um novo método chamado “retornaCaminhoTypesafeEnum()”:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
private function retornaCaminhoTypesafeEnum(tamanho:ImageSizeEnum):String
            {
                var caminho:String;
                switch(tamanho)
                {
                    case ImageSizeEnum.PEQUENO:
                    {
                        caminho = "http://www.suaurl.com/imagem_pequena.jpg";
                        break;
                    }
                    case ImageSizeEnum.MEDIO:
                    {
                        caminho = "http://www.suaurl.com/imagem_media.jpg";
                        break;
                    }
                    case ImageSizeEnum.GRANDE:
                    {
                        caminho = "http://www.suaurl.com/imagem_grande.jpg";
                        break;
                    }
                    default:
                    {
                        caminho = "[ERRO]";
                    }
                }

                return caminho;
            }

Para utilizá-lo faça:

1
trace( retornaCaminhoTypesafeEnum(ImageSizeEnum.GRANDE) );

Faça alguns testes, tente instanciar nosso Enum para criar um novo tipo:

1
var enum:ImageSizeEnum = new ImageSizeEnum("novo_tipo");

Como resultado você deve ter recebido um erro em tempo de execução com a mensagem: “Você não pode instanciar um Typesafe Enum”.

Agora tente passar uma string qualquer como argumento do método “retornaCaminhoTypesafeEnum()”:

1
trace( retornaCaminhoTypesafeEnum("novo_tipo") );

Você deve ter visto um erro em tempo de compilação uma vez não ser possível passar como argumento do método uma string quando ele espera o tipo “ImageSizeEnum”.

Bom galera espero que tenham gostado. Veja aqui um projeto de exemplo.

Até a próxima!

Nov 5

Scala – Primeiros Passos

Escrito por DClick Team em 1, 4, 6, análise, AR, arte, auto, back, BI, blog, boolean, break, bug, busca, case, class, classe, classes, codec, código, comparação, comunidade, control, Curso, Cursos, demo, Desenvolvimento, Design, Documentação, Download, Eclipse, err, erro, error, eval, exemplo, Exemplos, Ferramenta, for, futuro, Geral, git, ide, IE, if, image, int, internet, Java, Javascript, loop, Mac, mg, novidade, O, on, oop, Orientação, Orientação a Objetos, Otimização, Outros, padrão, print, problema, problemas, programação, Projetos, pt, rest, RIA, Ria’s Geral, RoR, string, Sun, tag, TAT, Tema, Teste, Tutoriais, Tutorial, Twitter, UI, uint, Vários, XP, zend @ 11 5th, 2010 | via http://blog.dclick.com.br/pt/ | Sem comentários
DClick Team
? X
  • Bookmarks

Blinkbits BlinkLists BlogLines Blogmarks Buddymarks CiteULike Co.mments Del.icio.us Digg Diigo

Fark Feed Me Links Furl Google Linkagogo ma.gnolia Mister Wong Newsvine Propeller Rawsugar

Reddit Rojo Simpy Sphinn Spurl Squidoo StumbleUpon Tailrank Technorati Yahoo

More »

Twitter!


Aprendendo Scala

Estou começando uma série de posts sobre Scala para divulgar as minhas experências com a linguagem e suas aplicações. Vou tentar passar o funcionamento da linguagem e seus recursos, assim como também um pouco do paradigma de programação funcional, e tentar chegar em aplicações práticas no ambiente de desenvolvimento.

Existem alguns tutoriais disponíveis na internet bem interessantes mas que as vezes jogam muito conteúdo sem dar tempo para assimilar os conceitos. Nessa série de posts tentarei colocar os conceitos e ferramentas de Scala e linguagens funcionais de uma maneira natural, conforme eu mesmo for evoluindo na linguagem e também dando exemplos e exercícios para que você possa assimilar o que está sendo passado. Vou tentar explicar também conceitos mais teóricos do paradigma funcional, para que a linguagem que estamos falando seja a mesma.

Minha experiência com Scala é algo bem próximo do zero, por isso estou escrevendo esta série de posts com o intuito de me forçar a estudar a linguagem e também ajudar a divulgar uma das possíveis alternativas ao Java, afinal se trata de uma linguagem nova e que ainda não foi muito difundida na comunidade. Tratarei bem do básico nos primeiros posts com exemplos bem trivias apenas para ajudar na compreensão dos conceitos básicos. Também colocarei algumas bibliografias de onde se pode encontrar documentação sobre a linguagem.

Linguagens funcionais e Scala

Não é nova a ideia de se programar em um paradigma funcional. Linguagens funcionais existem a quanse tanto tempo quanto existe linguagens de programação. Com certeza na sua faculdade você viu, ou verá, linguagens como LISP, Scheme, Erlang, Clojure, etc… e atualmente que está ficando bem conhecida: Scala que roda em cima da JVM, a virtual machine do Java. Linguagens funcionais mudam o paradigma para focar em ‘funções’. Assim como em linguagens orientadas a objeto onde a unidade básica é uma intância de um objeto, em linguagens funcionais a unidade básica é uma função. Uma função nada mais é do que uma operação que recebe parâmetros, executa alguma ação e devolve um resultado. O funcionamento é muito parecido com o dos métodos em linguagens orientadas a objeto.

O interessante sobre Scala, é que a linguagem permite uma mescla do paradigma funcional com orientação a objeto. Existem conceitos de ambos implementados na linguagem e que fazem sentido quando aplicados em conjunto. Por exemplo, em scala existe o conceito de classe e de instâncias de classes, que são os objetos. Também existem funções que independem de uma classe para existirem. Se trata de um conceito muito poderoso, pois possibilita toda padronização e controle do design do sistema que as linguagens orientadas a objeto permitem, sem restringir o uso do dinamismo e abstração da linguagem funcional.

Mas claro que Scala e linguagens funcionais tem seus problemas. Por exemplo, não existe uma IDE sólida como o Eclipse ou o NetBeans para Scala. O que dificulta no momento de trabalhar com projetos muito grandes, com uma equipe com vários programadores. O dinamismo da linguagem também impede uma análise de código que por exemplo o PMD, ou o FindBugs disponibilizam no Java. Dessa forma, deveríamos garantir que as boas práticas e o design está sendo seguido com nossos testes unitários.

Chega de filosofar sobre a linguagem, vamos para a parte prática.

Instalando Scala

Para instalar o Scala basta acessar a página oficial de download neste link, e fazer o download de acordo com sua plataforma. Feito isso, descompacte o conteúdo em alguma pasta na sua máquina e adicione a pasta ‘bin‘ ao path do seu sistema operacional. Para se certificar que foi tudo instalado corretamente, abra um console e digite ‘scala‘, o terminal do scala deve abrir e aparecer uma tela como essa:

Agora que o terminal está sendo executado, digite ‘1 + 1‘ e repare na saída:

1
res0: Int = 2

É uma saída um tanto quanto confusa, mas que faz sentido no contexto do Scala. O que está acontecendo é que a unidade básica em Scala é uma função, portanto a operação + também é uma função, que foi executada no objeto ‘1‘, passando o parâmetro ‘1‘. Para se ter uma idéia melhor desse funcionamento, digite o seguinte no terminal:

1
scala> 1.+(1)

e aperte Enter. Repare na saída:

1
res1: Double = 2.0

Com exceção do tipo que era int e agora é Double, o funcionamento é exatamente o mesmo. Tal sintaxe já deve estar bem claro na cabeça da maioria dos programadores, mas a primeira sintaxe é só uma maneira difetente de se fazer a mesma chamada.

Conceitos básicos da linguagem

Vamos definir uma função para entender um pouco mais da sintaxe. Digite o seguinte:

1
2
scala> def a = 2 + 2
a: Int

Aqui estamos definindo uma função com o nome ‘a‘ que não recebe parâmetros, e devolve o resultado da soma ‘2 + 2‘. A palavra restrita return não é necessária, o compilador consegue inferir que a última expressão da função será o valor devolvido. Repare também que não precisamos definir o tipo que a função devolve, o qual também foi inferido pelo compilador. Portanto ao contrário do que possa parecer, Scala é uma linguagem tipada em tempo de compilação, portanto o seguinte trecho não compila:

1
2
3
4
5
6
7
8
9
scala> var b = “abc”
b: java.lang.String = abc

scala> b = a
<console>:7: error: type mismatch;
 found   : Int
 required: java.lang.String
       b = a
           ^

Repare que o compilador inferiu que o tipo da variável ‘b‘ é String (note que é o String do java), e que o tipo devolvido por ‘a‘ é Int, logo o código não compila. De certa forma esse comportamento é bom, pois garante uma maior integridade do código, sem que você tenha que programar para “deixar o compilador feliz“, ou seja, não existem tantas regras na escrita do código, porque muitas podem ser deduzidas a partir do contexto.

Um outro conceito de Scala é a diferença entre chamada por valor, e chamada por nome. Na chamada por valor é feita a evaluação da expressão assim que o código é executado, mesmo que não seja necessário usar o resultado da chamada. A vantagem é que evitamos executar outras vezes a expressão para obter o resultado, pois este já foi determinado. Na chamada por nome a evaluação da expressão ocorre apenas quando o resultado da chamada será usado, tendo um comportamento mais lazy. A desvantagem é a execução da expressão várias vezes para se obter o mesmo resultado, mas a vantagem é não fazer a execução quando não for necessário. Vamos ver um exemplo da diferença entre a chamada por valor e por nome. Volte no terminal e defina a seguinte função:

1
2
scala> def loop: Int = loop
loop: Int

Agora defina uma função que recebe dois inteiros e devolve o primeiro:

1
2
scala> def primeiro(x: Int, y: Int) = x
primeiro: (x: Int,y: Int)Int

Agora execute a chamada passando ‘loop‘ como segundo parâmetro e se prepare porque seu console irá travar na execução =):

1
2
scala> primeiro(0, loop)
_

Vamos fazer uma pequena modificação na definição de ‘primeiro‘ para tornar possível a execução de tal código:

1
2
scala> def primeiro (x: Int, y: => Int) = x
primeiro: (x: Int,y: => Int)Int

O que definimos agora foi que o segundo parâmetro de ‘primeiro‘ será uma função que devolve um Int. Assim seu resultado só será obtido quando for feita a chamada direta na expressão. Agora conseguimos fazer a chamada em nossa função:

1
2
scala> primeiro(0, loop)
res0: int = 0

Nossa função executou e finalizou sem problemas dessa vez, isso porque não foi necessário utilizar o segundo valor para obter o resultado. Essa é chamada por nome, e o primeiro exemplo é a chamada por valor.

Até agora vimos como invocar funções, como definir funções (def) e como definir variáveis (var). Vimos também o básico de inferência de tipo pelo compilador do scala e os primeiros conceitos da linguagem. Mas como eu havia dito, Scala também tem conceitos de orientação a objetos, portanto vamos definir nossa primeira classe em Scala:

1
2
scala> class AcumulaSoma { var acumulado = 0; def acumula(i: Int) = { acumulado = acumulado + i; acumulado } }
defined class AcumulaSoma

Lembre-se que não somos obrigados a definir o tipo devolvido pela função caso esteja explícito e também não precisamos da palavra reservada ‘return‘. O que fizemos foi definir uma classe que se chama ‘AcumulaSoma‘ que tem um atributo, que por padrão do Scala é de acesso privado, que se chama acumulado e que o compilador inferiu o tipo inteiro baseado no valor atribuído. Também definimos para a classe a função ‘acumula‘ que recebe um inteiro, guarda o valor acumulado até então da soma com o parâmetro passado e devolve tal valor. Vamos instanciar um objeto da nossa classe e fazer a chamada ao método:

1
2
scala> val ac = new AcumulaSoma
ac: AcumulaSoma = AcumulaSoma@cbbe37

Algumas diferenças com o Java (supondo que estamos mais acostumados com a sintaxe do Java) já podem ser notadas. Além da inferência do tipo de ‘ac‘ para ‘AcumulaSoma‘, criamos ‘ac‘ com a a palavra reservada ‘val‘, ou seja, estamos dizendo que diferente de ‘var‘ onde criamos uma variável, estamos criando um valor e estamos garantindo em tempo de compilação que este valor não pode ser alterado no código. No Java teríamos que usar a palavra ‘final‘ para obter o mesmo comportamento, em Scala temos que “satisfazer menos o compilador“. Também não foi necessário usar ‘()‘ para invocar o construtor de AcumulaSoma, e assim como no Java toda classe em Scala tem por padrão o construtor que não recebe parâmetros com acesso público. Continuando o exemplo:

1
2
3
4
5
scala> ac.acumula(2)
res0: Int = 2

scala> ac.acumula(1)
res1: Int = 3

Nada de novidade aqui, estamos invocando a função ‘acumula‘ no objeto ‘ac‘. Porém ‘acumula‘ é uma função que recebe um único parâmetro e devolve um valor. Dessa forma podemos executar a chamada da nossa função da outra forma que vimos anteriormente:

1
2
scala> ac acumula 4
res2: Int = 7

No Java conseguimos definir classes estáticas. Em Scala não existe exatamente o conceito de classes, atributos e parâmetros estáticos, porém existe um conceito mais bem definido: ‘object‘. Criamos um ‘object‘ igual criamos uma classe, com a diferença de que não é possível instanciarmos um object, afinal estamos definindo o próprio. Com essa diferença, estamos garantindo em tempo de compilação que o design do código, em que foi tomada a decisão de restringir a existência de apenas uma definição para determinada classe seja seguida. Em Java também é possível garantir tal critério em tempo de compilação, mas demanda a escrita de bem mais código e de uma compreensão um pouco maior do funcionamento e limitações da linguagem. Um exemplo de object:

1
2
3
4
5
scala> object Objeto { def valor = 5 }
defined module Objeto

scala> Objeto.valor
res3: Int 5

Existem os tipos primitivos básicos em Scala como Int, Long, Boolean, Float, Double, Short, Byte, Char e String, sendo que String é a String do ‘java.lang‘. Um fato interessante sobre Scala é que como a linguagem roda em cima da JVM, todas as bibliotecas disponíveis para Java também estão disponíveis para Scala.

O tipo que não vimos ainda é o ‘void‘. Em Scala não existe o conceito de void, toda função devolve um valor e quando não há um valor explícito a ser devolvido o compilador se encarrega de devolver um valor do tipo ‘Unit‘. Exemplo:

1
2
scala> def imprime = print(“Hello!”)
imprime: Unit

‘print’ é uma função que imprime um valor no terminal e não devolve valor, logo nossa função ‘imprime‘ também não devolve valor, portanto o tipo devolvido é ‘Unit‘, que também pode ser expressado/escrito como ‘()‘. A diferença básica entre void e Unit, é que Scala permite criar valores e variáveis do tipo Unit, e em Java por exemplo não é possível criar uma variável do tipo void. Também é possível analisar o valor devolvido por qualquer função mesmo que a função não devolva um valor definido e neste caso será um Unit. Um exemplo trivial de como usar este comportamento:

1
2
3
4
5
scala> def num = 9
num: Int

scala> def verificaUnit(f: => Any) = { f match { case x:Unit => print(“Eh Unit!”) case _ => print(“Nao eh Unit!”) } }
verificaUnit: (f: => Any)Unit

O tipo ‘Any‘ é análogo ao ‘Object‘ do Java, portanto pode ser qualquer valor, função ou objeto.

Nessa função estamos usando um tipo de switch case para obter o mesmo comportamento do ‘instanceof‘ em Java, afinal não existe tal operação em Scala. O que está acontecendo é que a função verificaUnit recebe uma função que não recebe argumentos e devolve um valor qualquer. A função ‘f‘ é então evaluada e o resultado da função é testado nos cases da operação ‘match‘. Caso seja do tipo Unit, imprimimos “Eh Unit!”, e no caso padrão imprimimos “Nao eh Unit!”. Repare que diferente do ‘switch‘, no ‘macth‘ não temos que chamar a operação ‘break‘ para não executar os outros casos. Para testar verificaUnit vamos fazer a chamada usando nossas outras duas funções que foram definidas:

1
2
3
4
scala> verificaUnit(num)
Nao eh Unit!
scala> verificaUnit(imprime)
Hello!Eh Unit!

Um exemplo mais prático

Vamos implementar um exemplo um pouco mais prático que calcula a raiz quadrada aproximada de um número. Para isso vamos usar o método de Newton de aproximações sucessivas. A idéia é bem simples, nada mais é do que uma busca binária entre os palpites que se aproximam cada vez mais da raiz quadrada do número passado. Vamos começar definindo uma função que diz se a raiz encontrada é boa o suficiente para ser o resultado:

1
2
3
4
5
scala> def abs (x: Double) = if (x > 0) x else -x
abs: (x: Double)Double

scala> def proximaOSuficiente(palpite: Double, x: Double) = abs((palpite * palpite) – x) < 0.0001
proximaOSuficiente: (palpite: Double,x: Double)Boolean

O bloco if é igual a sintaxe usada no Java, o mesmo vale para o else e o else if. Na segunda função estamos verificando se o número elevado ao quadrado é próximo o bastante do original. Agora vamos definir a função que faz um palpite melhor:

1
2
scala> def melhoraPalpite(palpite: Double, x: Double) = (palpite + x / palpite) / 2
melhoraPalpite: (palpite: Double,x: Double)Double

O que fizemos foi pegar um número para palpite que está entre o nosso palpite anterior e x dividido sobre o palpite anterior, onde x é o número que queremos obter a raiz quadrada. O método de Newton garante que para x >= 1 essa aproximação é sempre válida. Vamos agora a função que executa o método de Newton propriamente dito:

1
2
3
scala> def raizNewton(palpite: Double, x: Double): Double =
     | if (proximaOSuficiente(palpite, x)) palpite else raizNewton(melhoraPalpite(palpite, x), x)
raizNewton: (palpite: Double,x: Double)Double

Estamos calculando a raiz quadrada de modo recursivo até que o resultado seja bom o suficiente. Agora basta definir uma base para nossa função, para isso iremos pré-definir um valor para o palpite base, guardando a chamada nesse escopo em uma outra função:

1
2
scala> def raizQuadrada(x: Double) = raizNewton(1, x)
raizQuadrada: (x: Double)Double

Pronto, basta brincar com algumas chamadas para nossa função que calcula a raiz quadrada =).

1
2
scala> raizQuadrada(169)
res4: Double = 13.000000070110696

O resultado obtido não é muito preciso, mas também essa não é a melhor maneira de se calcular a raiz quadrada, inclusive para números muito grandes o algorítmo não funciona por restrições com a precisão do Double.

Algumas Considerações

A grande moda das linguagens funcionais está surgindo porque acreditasse que elas são o futuro para a programação concorrente e paralela, de que se o seu programa foi escrito em uma linguagem funcional você terá ganho o benefício da execução concorrente sem grandes esforços, bem, isso não é verdade. Linguagens funcionais como qualquer outro paradigma necessitam que o programa seja escrito de maneira que seu design seja voltado para execução concorrente ou paralela, a difenrença é que a sintaxe e as ferramentas disponíveis nas linguagens funcionais facilitam tal design.

Existem algumas técnicas de programação que surgiram com linguagens funcionais, como por exemplo Recursão em Cauda, que não entrarei no mérito nesse post mas que vale a pena pesquisar sobre o assunto. Tais técnicas facilitam a vida do compilador no momento em que for possível ser feita algum tipo de otimização.

Uma comparação que logo surge na cabeça dos programadores é: qual linguagem é melhor, Scala ou Java? A resposta é fácil… nenhuma. Cada linguagem tem um escopo e paradigma de atuação diferente, não tem como comparar ambas. O que talvez faça sentido comparar sejam fatores mais fora do domínio da linguagem, como por exemplo o tamanho da comunidade que utiliza efetivamente a linguagem, o tipo de suporte, a documentação disponível, as restrições de uso, mas em geral depende do caso de uso específico para o seu problema, e principalmente do gosto do programador.

Por enquanto é isso, em um próximo post tratarei de alguns outros tipos de funções e falarei um pouco mais sobre currying. Também darei exemplos de tipos diferentes de declarações de classes e objetos.

Referência: Scala By Example, Martin Odersky

« Entradas anteriores |

ACERCA

O que é o RedeRIA ?

O redeRIA não é nada mais que um agregador de feed's que disponibiliza o conteudo de varios blogs e autores ao redor do mundo RIA, actualmente agregamos mais de 2755 entradas vindas de 53 blogs especializados em ria’s, pelo que só fica a ganhar em assinar o feed ou seguir a comunidade no twitter.

Se acha que o seu blog ou um blog de um amigo é interessante e util para os leitores o redeRIA, faça a sua submissão aqui.

Feed: assine já
Twitter: siga-nos

GOOGLE

Votação


Deveria o RedeRia agregar conteúdo em inglês?
Ver Resultados

AUTORES


Eduardo KrausAlexandre TadashiBindableCognitiva SoluçõesDaniel LopesDaniel SchmitzDanielPedrinhaDClick TeamEbercomEdgard DavidsonElvis FernandesErko BrideeFabiel PrestesFábio Batista da SilvaFabio da SilvaFabriccio BernardesFelipe BorellaFlavia MoreiraGabriel VersalliniGabriela T. PerryIgor MusardoJanderson CardosoJoão AugustoJose Carlos FielKelps SousaLeonardo FrançaLucas MarçalLuis MessiasLuiz TarabalMario JuniorMário SantosMauro MartinsPablo SouzaPedro ClaudioreneRia BrazilriaPTRicardo CerqueiraRobson FernandesRodrigo Pereira FragaSaintBrSamuelFacchinelloSergio SouzaSilva DeveloperStefan HorochovecTech CaffeTecinforThiago BuenoVedVinícius SandimWillian ManoXAML Cast

PUBLICIDADE








Powered by Wordpress & msdevstudio.com