framework web vaadin

33
 Centro Universitário de Formiga – Unifor MG Frame work Web Vaadin Aluno: Pedro Taylon Carvalho Disciplina: Laboratório de Programação IV Prof: Michel Pires

Upload: cleonilson-vieira

Post on 21-Jul-2015

790 views

Category:

Documents


0 download

TRANSCRIPT

Centro Universitrio de Formiga Unifor MG

Framework Web Vaadin

Aluno: Pedro Taylon Carvalho Disciplina: Laboratrio de Programao IV Prof: Michel Pires

Introduo ao VaadinVaadin um framework de aplicaes web para Rich Internet Applications (RIA). Em contraste com as bibliotecas Javascript e browser-plugin solues baseadas, possui uma arquitetura de servidor robusto. Isto significa que a maior parte da lgica de aplicativo executado de forma segura no servidor. Google Web Toolkit (GWT) usado no lado do navegador para assegurar uma experincia de usurio rica e fluente. Vaadin uma grande coleo de componentes de interface do usurio. Para compor a interface de usurio do aplicativo a partir de componentes como botes, tabelas, rvores e Layouts. Os componentes de uso eventos, ouvintes e ligao de dados para comunicar uns com os outros e com sua lgica de negcio. Vaadin uma arquitetura robusta para desenvolvimento rpido de aplicaes. A arquitetura baseada em componentes, juntamente com tipagem esttica linguagem Java e caractersticas de ligao de dados para ajud-lo a construir aplicaes que so facilmente modularizadas e refatoradas, conforme necessrio. O IDE e suporte a ferramentas, incluindo ferramenta de design visuais ajudam a construir interface web extremamente rpida. Embora fcil de usar, Vaadin tem demasiadas funcionalidades para enumer-los todos em uma nica pgina. Abaixo, segue uma lista dos destaques do recurso, normas e informaes de compatibilidade que o diferencia de outros frameworks UI web. Quadro abrangente de componentes: Um grande conjunto de componentes de interface do usurio, controles e widgets; Widgets rico e interativo com lazy-loading; Arrastar e soltar apoio; Suporte evento mvel toque; Ligao de dados usando MVC (Model-View-Controller); Construir layouts em Java ou em HTML - ou ambos; Criar novos componentes com composio e inheritace;

Aparncia personalizvel CSS styling poderoso componente com base Boa aparncia built-in temas e estilos Construir temas de aplicativos personalizados Incorporar a qualquer pgina web

Java Web Development Modelo poderoso de programao do lado do servidor Implantao de um nico Jar-simples desenvolvimento web orientado a objeto

Arquitetura de aplicaes Web seguras Do lado do servidor de gerenciamento de estado; O cdigo do aplicativo executado no servidor; Parmetro seguro e validao de solicitao;

Compatibilidade Web Com base no Google Web Toolkit (GWT); Sem plugins necessrios browser; Janela do navegador e suporte guia; Suporte ao boto Voltar Suporte profunda ligao Parmetro URL e manuseio fragmento

Instalao no Netbeans1 - Entre no seguinte endereo 'https://vaadin.com/netbeans' e baixe o plugin 'Vaadin NetBeans plugin NBM installation package'; 2 - Abra o Netbeans; 3 - Entre na aba Ferramentas (tools) plugins (plugins) baixados (downloaded); 4 - Clique em Adicionar Plugins (Add Plugins), encontre o plugin e clique em Instalar (Install) e aceite todos os termos;

5 - Depois de tudo concludo, pronto crie um projeto para verificar se tudo est correto;

Criando o Primeiro Projeto1 - Selecione Arquivo (File) Novo (New) Projeto (Project); 2 - Selecione Aplicao Web (Web Application) para o categoria Java Web; 3 - Preencha as informaes bsicas do seu projeto e selecione Vaadin na etapa de Frameworks;

Rodando o Projeto1 - Boto direito do mouse seu projeto recm-criado e selecione Executar; 2 - Abra o aplicativo em um navegador web (se no for aberto automaticamente) v para o seguinte endereo http://localhost:8080// A seguinte pgina ser exibida:

Confirmando ento o sucesso da instalao do plugin. O editor visual para o Netbeans foi desenvolvido, mas ainda no satisfatrio e algumas verses nem instalam.

Instalando o Vaadin e o Editor Visual no Eclipse1 - V em Help Install new Software 2 - Adicione um novo repositrio Add new Repository http://vaadin.com/eclipse 3 Marque todos os checkbox e pronto o eclipse j esta pronto para rodar. Tela mostrando o resultado da instalao:

O editor visual facilita o desenvolvimento de layouts, design e melhorando assim a produtividade.

TutorialO mtodo init() em nossa aplicao chamada que uma cada nova aplicao precisa ser inicializado ou seja, quando um novo usurio navega para a nossa aplicao. Para manter o init() mtodo simples no vamos construir o nosso layout principal l, mas em um mtodo separado (buildMainLayout ()) que ns chamamos de init (). Por isso, vamos comear por criar o mtodo chamado buildMainLayout () e adicionar uma chamada para esse mtodo a partir do mtodo init (). O cdigo deve ficar assim:@Override public void init() { buildMainLayout(); }

Em seguida, vamos adicionar alguns componentes que devem estar na tela o tempo todo. Vamos armazenar estes em campos como precisamos referenci-los mais tarde. Estes so:private private private private private Button newContact = new Button("Adicionar Cliente"); Button search = new Button("Procurar Cliente"); Button share = new Button("Adicionar Produto"); Button help = new Button("Help"); SplitPanel horizontalSplit = new SplitPanel( SplitPanel.ORIENTATION_HORIZONTAL);

Construindo o layout Principal Em seguida, vamos criar um VerticalLayout, o layout para a nossa janela principal e faz-lo consumir todo o espao disponvel na janela. Ento ns criamos um novo HorizontalLayout para a barra de ferramentas e preench-lo com nossos botes. Finalmente, adicionar o painel de diviso horizontal para layout principal da janela. Separamos a criao da barra de ferramentas a um mtodo prprio, createToolbar (), para manter o cdigo mais limpo. Acabamos com o seguinte cdigo:private void buildMainLayout() { setMainWindow(new Window("Address Book Demo application")); VerticalLayout layout = new VerticalLayout(); layout.setSizeFull(); layout.addComponent(createToolbar()); layout.addComponent(horizontalSplit); layout.setExpandRatio(horizontalSplit, 1); horizontalSplit.setSplitPosition(200, SplitPanel.UNITS_PIXELS); getMainWindow().setContent(layout); }

public HorizontalLayout createToolbar() { HorizontalLayout lo = new HorizontalLayout(); lo.addComponent(newContact); lo.addComponent(search); lo.addComponent(share); lo.addComponent(help); return lo; }

Populando o layout com componentes: Agora temos um esqueleto de aplicao muito bsico pronto. O resto das partes UI precisamos criar atravs da extenso de componentes existentes. Vamos estender componentes bsicos e ajustlos para uso em nossa aplicao. Vamos comear com uma rvore de navegao. Crie uma classe NavigationTree estender o componente rvore em um novo pacote chamado "ui". Eclipse vai fazer mais isto para voc quase que automaticamente. Adicionar duas linhas de cdigo para rvore no construtor. Voc vai acabar com a classe a seguir:public class NavigationTree extends Tree{ public public public public public public static static static static static static final final final final final final Object Object Object Object Object Object cadastrarProduto excluirProduto cadastrarCliente excluirCliente realizarVenda alteraVenda = = = = = = "Cadastrar Produto"; "Excluir Produto"; "Cadastrar Cliente"; "Excluir Cliente"; "Realizar Venda"; "Alterar Venda";

public NavigationTree(){ addItem(cadastrarProduto); addItem(excluirProduto); addItem(cadastrarCliente); addItem(excluirCliente); addItem(realizarVenda); addItem(alteraVenda); } }

Agora vamos adicionar a rvore de navegao para a nossa classe de aplicativo. Vamos precisar fazer referncia a ela mais tarde para que armazen-lo em um campo:private NavigationTree tree = new NavigationTree();

Ento ns colocamos como o primeiro componente para o painel de diviso horizontal em buildMainLayout ().

horizontalSplit.setFirstComponent(tree);

Em nossa aplicao vista principal ser sempre usar o lado direito do painel dividido horizontal. Vamos comear fazendo uma setter genrico para a tela principal no AddressBookApplication:private void setMainComponent(Component c) { horizontalSplit.setSecondComponent(c); }

Queremos que este seja um mtodo separado para que possamos us-lo mais tarde para alterar o componente principal (view). Agora vamos criar um ListView, que a nossa viso principal que mostrado quando o aplicativo iniciado. Ns cri-lo da mesma maneira como o NavigationTree mas em vez de estender SplitPanel Tree. Este painel deve ser dividida vertical, que o padro para os painis de diviso. Ns s precisamos de uma classe vazia com um construtor at o momento.package com.vaadin.demo.tutorial.addressbook; import com.vaadin.ui.SplitPanel; public class ListView extends SplitPanel { public ListView(){ } }

Para minimizar o tempo de inicializao e uso de memria, vamos utilizar um padro de inicializao lenta para a criao de nossos pontos de vista. Em um aplicativo este pequeno ele realmente no importa, mas geralmente um hbito muito bom para voc preguiosamente instanciar objetos GUI. Portanto, criar um campo para o ListView na classe principal da aplicao e criar um getter preguioso para ele assim:public class ListView extends SplitPanel { private ListView listView = null; public ListView(){ }

private ListView getListView(){ if (listView == null) { listView = new ListView(); } return listView;

} }

O mtodo cria o ponto de vista quando necessrio, pela primeira vez, apenas a criao de pontos de vista realmente utilizados. Agora teste isso alterando o cdigo no mtodo init() para:setMainComponent(getListView());

Agora vamos criar os componentes que queremos colocar no ListView. O primeiro componente (lista de Clientes) ser estendido a partir da Tabela de modo que criar uma classe de sub tabela chamado ClientList. Em seu construtor vamos acrescentar alguns dados fictcio para ela e tambm definir o tamanho para torn-lo consumir todo o espao disponvel que lhe dado pelo painel de dividir. Vamos acabar com a classe stub seguinte:package com.vaadin.demo.tutorial.addressbook.UIcomponents; import com.vaadin.ui.Table; public class ClientList extends Table{ public ClientList() { addContainerProperty("Nome", String.class, "Mark"); addContainerProperty("Sobrenome", String.class, "Smith"); addItem(); addItem(); setSizeFull(); } }

Em seguida, criamos o espectador/editor para os nossos contatos (PersonForm) da mesma forma, estendendo Forma:import import import import com.vaadin.ui.Button; com.vaadin.ui.Form; com.vaadin.ui.HorizontalLayout; com.vaadin.ui.TextField;

public class ClientForm extends Form { private Button save = new Button("Salvar"); private Button cancel = new Button("Cancelar"); public ClientForm() { addField("Nome", new TextField("Nome")); addField("Sobrenome", new TextField("Sobrenome"));

HorizontalLayout footer = new HorizontalLayout(); footer.setSpacing(true); footer.addComponent(save); footer.addComponent(cancel); setFooter(footer); } }

Modificar o construtor ListView para que possamos passar os componentes a ele e adicion-los ao painel de dividir. Modificar o getter ListView para instanciar os novos componentes e tambm salvar uma referncia para eles. Voc vai acabar tendo o seguinte cdigo em sua classe de aplicao:private ListView getListView(){ if (listView == null) { clientlist = new ClientList(); clientform = new ClientForm(); listView = new ListView(clientlist, clientform); } return listView; }

E as seguintes no construtor ListView:public ListView(ClientList clientlist, ClientForm clientform){ setFirstComponent(clientlist); setSecondComponent(clientform); setSplitPosition(40); }

Eis o resultado parcial do desenvolvimento do tutorial:

Sub-Janelas Vaadin possui dois tipos de janelas: janelas de nvel superior e sub janelas.

Tradicionalmente janelas que no so muito utilizados em aplicaes web, mas durante a "Web 2.0" era o tipo de janelas dentro das janelas do navegador se tornou bastante comum. Sub janelas so adicionados ao nvel superior janelas (navegadores web windows). Com o uso moderado de janelas sub pode-se fazer a aplicao se sentir mais como uma aplicao desktop e realmente melhorar a usabilidade. Sub janelas so mostradas na aplicao, adicionando-os a uma janela de nvel superior usando a addWindow (janela Window) mtodo. Mais comumente como o seguinte:getMainWindow().addWindow(mySubWindow);

Ns vamos fazer duas janelas de sub para nossa aplicao. Um deles uma janela de ajuda que ser flutuando sobre a interface do usurio principal. O usurio pode arrast-lo para algum lugar onde no atrapalha o uso do aplicativo e redimension-lo para que ele no est no caminho. A outra janela uma sub (no funcionais) de compartilhamento de tela de opes. Ele ir demonstrar como criar uma caixa de dilogo modal que bloqueia o resto da interface do usurio at que ele esteja fechado. Ambas as janelas estender janela e so criados muito da mesma forma como ListView e SearchView acima. Implementaes esto abaixo:package com.vaadin.demo.tutorial.addressbook.ui; import com.vaadin.ui.Label; import com.vaadin.ui.Window; public class HelpWindow extends Window { private static final String HELP_HTML_SNIPPET = "This is " + "an application built during Vaadin " + "tutorial. Hopefully it doesn't need any real help."; public HelpWindow() { setCaption("Address Book help"); addComponent(new Label(HELP_HTML_SNIPPET, Label.CONTENT_XHTML)); } } package com.vaadin.demo.tutorial.addressbook.ui; import import import import com.vaadin.ui.Button; com.vaadin.ui.CheckBox; com.vaadin.ui.Label; com.vaadin.ui.Window;

public class SharingOptions extends Window { public SharingOptions() { setModal(true);

setWidth("50%"); center(); setCaption("Opoes compartilhadas"); addComponent(new Label( "With these setting you can modify contact sharing " + "options. (non-functional, example of modal

dialog)")); addComponent(new CheckBox("Gmail")); addComponent(new CheckBox("Hotmail")); Button close = new Button("OK"); addComponent(close); } }

Agora criar mtodos getter preguioso para essas duas flutuante "views". No podemos test-los da mesma forma como outras vistas como no podemos adicionar uma janela como um componente. Em vez disso, podemos test-las usando o Window.addWindow () mtodo como este:getMainWindow().addWindow(getHelpWindow());

Nesta etapa ns cobrimos como construir o layout principal para nossa aplicao. Criamos componentes para navegar pelo programa, tanto na forma de botes e uma rvore de navegao. Tambm criamos a tabela que ir listar todos os nossos contactos e criou um formulrio para inserir dados. Finalmente, introduzimos janelas sub dentro da nossa aplicao e testados manualmente que tudo funciona como esperado. Em seguida, precisamos adicionar alguma lgica para a nossa aplicao para fazer as coisas acontecerem quando os botes so empurradas etc Mas antes disso vamos ver como vincular alguns dados para a nossa mesa.

Noes bsicas de ligao de dados Agora criamos a interface bsica para a nossa aplicao do catlogo de endereos e uma tabela (PersonList) onde todos os contatos devem ser exibidos. O prximo passo ligar os dados para o PersonList para torn-lo mostrar algo mais do que os dois "Mark Smith" linhas de teste que adicionou na etapa anterior. Queremos a nossa base de dados de tabela em uma simples Pessoa campos objeto java que contm, como firstName, lastName, email, etc Ns no queremos para preencher a tabela com a mo - em vez queremos usar instncias Pessoa para preencher a tabela. As instncias Pessoa real pode vir de qualquer lugar, em um caso real, provavelmente ser obtida a partir de um banco de dados, mas isso est fora do escopo deste tutorial. Ns, ao contrrio, gerar aleatoriamente Pessoa-objetos e us-los para demonstrar os recursos de ligao de dados. A classe Pessoa que estamos usando semelhante a:

package com.vaadin.demo.tutorial.addressbook.data; import java.io.Serializable; public class Person implements Serializable { private String firstName = ""; private String lastName = ""; private String email = ""; private String phoneNumber = ""; private String streetAddress = ""; private Integer postalCode = null; private String city = ""; // + setters and getters for all fields }

Ao preencher uma tabela existem alguns termos que devem ser compreendidos. Cada componente que inclui dados (por exemplo, uma tabela) tem um Container. O recipiente inclui todos os itens do componente. Um item corresponde a uma linha na tabela. Um item tem propriedades (Property), que em uma tabela correspondem s colunas em uma linha. Em aplicaes simples, podemos usar o addItem() mtodos na tabela para preench-lo com dados. O addItem() mtodos de adicionar itens (linhas), o qual, por sua vez pode ser preenchido pela adio de propriedades e definir valores para eles - bem como voc preencher uma tabela HTML tradicional, criando etiquetas e . O modelo de dados em Vaadin tambm contm recursos muito mais poderosos do que isso. Cada mesa conectada a uma fonte de dados que na verdade contm todos os dados exibidos na tabela. Uma fonte de dados pode realmente fornecer dados para qualquer tipo de componente como uma mesa, Select, rvore, etc A fonte de dados no contm necessariamente todos os itens da tabela, mas pode fornecer dinamicamente a tabela com dados de outra fonte quando a tabela de necessidades (por exemplo, de um banco de dados). A fonte de dados o que ns em Vaadin chamar um Container. A coisa agradvel com este container que ns podemos simplesmente: Instanciar o container Adicionar um nmero de objetos Pessoa a ele Atribuir o recipiente para uma tabela como fonte de dados A informao apresentada na tabela Neste caso, queremos usar um BeanItemContainer como o continer para os dados mostrados na tabela. Ele pode manter uma lista de objetos de nossa pessoa e fornecer a tabela com as informaes diretamente dos objetos quando necessrio.package com.vaadin.demo.tutorial.addressbook.data;

import java.io.Serializable; import com.vaadin.data.util.BeanItemContainer; public class PersonContainer extends BeanItemContainer implements Serializable { public PersonContainer() throws InstantiationException, IllegalAccessException { super(Person.class); } }

Alm disso o PersonContainer contm um mtodo esttico (createWithTestData ()) para a criao de um continer com dados de teste. Este consiste em um loop onde os objetos Pessoa com nomes aleatrios e outros dados gerado e ento adicionado ao container usando o addItem (Pessoa)mtodo. A gerao no ser descrito mais adiante neste tutorial ea PersonContainer.java pode ser baixado Para uma aplicao real do mundo conectado a um banco de dados que simplesmente substituir essa gerao de dados aleatrios com uma consulta de banco de dados que busca objetos reais. Um exemplo de como fazer isso com o Hibernate pode ser encontrada em http://dev.vaadin.com/wiki/Articles/UsingHibernateWithToolkit. Tabela de ligao para container Para usar este recipiente em nosso aplicativo, adicionar um novo campo para a nossa AddressBookApplication juntamente com um getter:private PersonContainer dataSource = PersonContainer.createWithTestData(); public PersonContainer getDataSource() { return dataSource; }

Alm deste, precisamos mudar o construtor PersonList assim passamos a instncia do aplicativo para ele (para que ele possa adquirir a sua fonte de dados). Alm disso, podemos remover o manequim criao de dados da etapa anterior, deixando a classe PersonList como:public class PersonList extends Table { public PersonList(AddressBookApplication app) { setSizeFull(); setContainerDataSource(app.getDataSource()); } }

O setContainerDataSource() define a fonte de dados para a tabela para a nossa prpria PersonContainer. Agora temos uma fonte de dados conectada a tabela e executar o aplicativo mostrar que a PersonList contm 100 linhas de dados, com base em 100 pessoas-objetos que foram gerados aleatoriamente.

A ordem das colunas ainda errado, queremos nome para vir em primeiro lugar, pelo menos. Alm disso os nomes dos campos da classe Pessoa no so realmente amigveis. Podemos lidar com isso adicionando duas arrays estticos para a classe PersonContainer (estes j estaro l, se voc baixou a classe).public static final Object[] NATURAL_COL_ORDER = new Object[] { "firstName", "lastName", "email", "phoneNumber", "streetAddress", "postalCode", "city" }; public static final String[] COL_HEADERS_ENGLISH = new String[] { "First name", "Last name", "Email", "Phone number", "Street Address", "Postal Code", "City" };

Alm disso ns adicionamos as seguintes linhas para a classe PersonList para classificar as colunas e tornar os cabealhos mais agradvel.setVisibleColumns(PersonContainer.NATURAL_COL_ORDER); setColumnHeaders(PersonContainer.COL_HEADERS_ENGLISH);

Neste passo, primeiro criou uma classe Pessoa para os itens que sero mostrados no livro de endereos. Em seguida discutimos Containers, itens e valores de propriedade - as partes centrais da ligao de dados em aplicaes Vaadin. Tambm introduziu o BeanItemContainer e estendeu-o para nossos prprios fins. Ns criamos alguns dados fictcios e acrescentou que a tabela com os mtodos discutidos acima. Esta exatamente a maneira que voc faria se ligam por exemplo, dados de um banco de dados ou o seu sistema de back-end para a camada de interface do usurio. Finalmente, tambm fez mesa mais legvel e mais bonito. Em seguida, vamos ver como o aplicativo iniciado para responder s interaes do usurio. Criando Interaes do Usurio Neste ponto ns temos um monte de componentes na tela e at mesmo uma fonte de dados preenchida com dados de teste ligado a nossa mesa. hora de comear a criar alguma lgica real em nossa aplicao. Vamos comear com uma viso simples de navegao proveniente usurio clicar em botes da barra de ferramenta, na rvore de navegao ou selecionar um item na tabela. Vamos ento continuar com algumas coisas mais avanadas na forma e o ponto de vista da pesquisa. Mas antes de tudo o que precisamos para criar uma viso de busca assim que ns temos algo para navegar. Ns s ir criar uma viso vazia neste momento para demonstrar navegao, pesquisa os componentes so adicionados mais tarde.package com.vaadin.demo.tutorial.addressbook.ui; import com.vaadin.demo.tutorial.addressbook.AddressBookApplication; import com.vaadin.ui.Panel; public class SearchView extends Panel { public SearchView(final AddressBookApplication app) {

setCaption("Search contacts"); setSizeFull(); } }

Ns usamos o mesmo tipo de inicializao lenta para este ver como fizemos para o ListView.private SearchView searchView = null; private SearchView getSearchView() { if (searchView == null) { searchView = new SearchView(this); } return searchView; }

Em nossa aplicao mais do tratamento de eventos feito pela classe principal do aplicativo. Este um trabalho e uma abordagem limpa para ligar a lgica de controle em aplicaes deste tamanho. Existem vrios outros mtodos para implementar manipulao de eventos como o uso de ouvintes em linha ou classes de ouvinte separado. Padres utilizados em outros frameworks como Swing GUI pode ser facilmente aplicada a um aplicativo Vaadin para que voc possa tirar proveito de suas experincias anteriores na programao GUI. O primeiro passo fazer com que a navegao entre o ponto de vista principal e do trabalho de pesquisa. Para navegar at o ponto de vista de pesquisa, temos um boto na barra de ferramentas. Vamos comear a partir da. Ir para o mtodo createToolbar () no AddressBookApplication e adicionar a seguinte linha perto do lugar que voc est adicionando o boto para o layout.search.addListener((Button.ClickListener) this);

Faa AddressBookApplication implementar Button.ClickListener e adicione o buttonClickMethod exigidos() para a classe AddressBookApplication. (Dica: voc vai fazer isso em cerca de 2 segundos com o recurso do Eclipse soluo rpida, use Ctrl-1). Agora que o aplicativo pode ouvir eventos de clique de boto, adicionar ouvintes de todos os outros botes criados em createToolbar () tambm. Vamos, mais tarde, usar o mesmo ouvinte para lidar com seus cliques tambm. Digite o seguinte cdigo de manipulao de eventos ao mtodo buttonClick ():final Button source = event.getButton(); if (source == search) { showSearchView(); }

Crie o mtodo showSearchView() (ou deixe o Eclipse cri-lo para voc). Queremos manter o cdigo limpo para que manter os manipuladores de eventos to pequeno quanto possvel e passar a lgica para a frente. Isto essencial, especialmente se voc estiver usando ouvintes que vai acabar por receber eventos a partir de componentes mltiplos.

O showSearchView () mtodo contm a lgica real, que extremamente simples, neste caso particular: vamos chamar o setMainComponent () com getSearchView (). O mtodo getSearchView () vai fazer a instanciao da viso preguiosa pesquisa, se necessrio e setMainComponent () ir substituir a viso atual com a viso de busca. Quando voc tiver adicionado o showSearchView () como abaixo, voc est pronto para testar seu programa.private void showSearchView() { setMainComponent(getSearchView()); }

Selecionar a Linha da Tabela Agora vamos concentrar-se na seleo de uma linha na tabela. Primeiro de tudo o que precisamos para definir a tabela no modo seleccionvel para que o usurio pode selecionar linhas. O valor de uma tabela corresponde a linha que est selecionada, o que significa que quando uma linha selecionada, um evento de alterao de valor enviado. Um ouvinte de alterao de valor , portanto, um bom lugar para reagir a interao do usurio. Adicionar um ouvinte de alterao de valor para a tabela, adicionando o seguinte cdigo para o construtor PersonList:setSelectable(true); setImmediate(true); addListener((Property.ValueChangeListener) app); setNullSelectionAllowed(false);

Agora volte para a Property.ValueChangeListener

classe AddressBookApplication. e adicione o valueChange

Torn-lo mtodo

implementar exigido ().

(Note que neste ponto voc pode ter que adicionar lana aos ouvintes o seu clique para que o mtodo addListener() pode decidir qual o ouvinte para adicionar). Agora vamos criar ou valor do identificador de alterao para a tabela. Nosso manipulador deve simplesmente recuperar o item selecionado da mesa e pass-lo para o PersonForm como fonte de dados para ele. Se a fonte de dados para a forma j este item que no precisamos fazer nada. O valueChange() mtodo deve ser semelhante a este:public void valueChange(ValueChangeEvent event) { Property property = event.getProperty(); if (property == personList) { Item item = personList.getItem(personList.getValue()); if (item != personForm.getItemDataSource()) { personForm.setItemDataSource(item); } } }

Agora experimente! Ao clicar em uma linha da tabela que voc deve obter as informaes para a pessoa selecionada exibida no formulrio abaixo. O formulrio no funciona corretamente ainda, mas vamos voltar a isso mais tarde. O prximo passo adicionar os ouvintes para a nossa rvore de navegao Com a nossa rvore de navegao que poderamos fazer exatamente o mesmo tipo de ouvinte de alterao de valor como fizemos para a tabela. rvore tambm uma classe de sub Select. Para uma rvore usado para navegao o evento de alterao de valor, no entanto, no o evento ideal. Ao clicar em um item j selecionado na rvore no ir disparar um evento de alterao de valor, mas muitas vezes necessrio para reagir tambm ao clicar em um item j selecionado. Como esta no pode ser realizado com um ouvinte de alterao de valor, usamos um outro tipo de ouvinte: ItemClickListener. ItemClickListeners so notificados a cada vez que um item clicado independente da seleo atual. Ouvir cliques item similar ao ouvir a cliques de boto. Ns adicionamos um gancho para o recipiente item (NavigationTree neste caso) e no ouvinte, podemos determinar o item que foi clicado usando o evento ItemClickEvent. Passos para fazer: Vamos implementar AddressBookApplication ItemClickListener e adicionar o mtodo necessrio. 1. Adicionar AddressBookApplication como um parmetro de construtor para NavigationTree e adicion-lo como um ItemClickListener no construtor NavigationTree. Embora no estamos interessados em selees em uma rvore, fazer selecionvel rvore tambm para que o usurio recebe um feedback ao clicar em um item. 2. Adicionar lgica para o manipulador de clique no item (itemClick ()) para reagir a Mostrar todas e Pesquisa. Aps as alteraes o NavigationTree deve ficar assim ...package com.vaadin.demo.tutorial.addressbook.ui; import com.vaadin.demo.tutorial.addressbook.AddressBookApplication; import com.vaadin.event.ItemClickEvent.ItemClickListener; import com.vaadin.ui.Tree; public class NavigationTree extends Tree { public static final Object SHOW_ALL = "Show all"; public static final Object SEARCH = "Search"; public NavigationTree(AddressBookApplication app) { addItem(SHOW_ALL); addItem(SEARCH); setSelectable(true); setNullSelectionAllowed(false); addListener((ItemClickListener) app); } }

... e os manipulaodres de click itemClick() no AddressBookApplication onde deve ficar assim:public void itemClick(ItemClickEvent event) { if(event.getSource() == tree) { Object itemId = event.getItemId(); if (itemId != null) { if (NavigationTree.SHOW_ALL.equals(itemId)) { showListView(); } else if (NavigationTree.SEARCH.equals(itemId)) { showSearchView(); } } } }

O new showListView() simplesmente chama setMainComponent() com Lembre-se que AddressBookApplication deve implementar ItemClickListener. Melhoria no formulrio

getListView().

Em seguida, vamos concentrar-se no formulrio. Queremos editar os detalhes existentes. O ouvinte de alterao de valor na tabela j coloca a pessoa selecionada no formulrio. Os valores tambm so atualizados no servidor. O que queremos fazer algumas melhorias de usabilidade: Utilize o formulrio como um visualizador detalhada (somente leitura), em primeiro lugar e tem um boto Editar para permitir a edio. Coloque a forma em um "buffer" modo para os dados do formulrio fica submetidos ao modelo de dados somente se salvar clicado. Um boto Cancelar deve retornar o formulrio para o estado de leitura apenas com os valores antigos. Faa os campos do formulrio aparecem na mesma ordem na tabela.

O primeiro passo mudar a ordem dos campos para que ele seja o mesmo que na tabela. Isto torna mais natural de preencher o formulrio. Podemos usar o mesmo mtodo com a tabela para ordenar os campos. Vamos comear a partir do construtor PersonForm e fazer as seguintes modificaes: remover campos dummy. adicionar uma referncia principal aplicao atravs do construtor. fazer o rodap do formulrio invisvel por padro (que no queremos mostrar o rodap quando o formulrio est faltando seu datasource ou seja, no mostrando qualquer Pessoa).

Aps estas modificaes o PersonForm parece com o seguinte. Note que voc tambm deve modificar a classe de aplicativo principal para passar-se na chamada do construtor PersonForm.

package com.vaadin.demo.tutorial.addressbook.ui; import import import import import import com.vaadin.demo.tutorial.addressbook.AddressBookApplication; com.vaadin.ui.Button; com.vaadin.ui.Form; com.vaadin.ui.HorizontalLayout; com.vaadin.ui.Button.ClickEvent; com.vaadin.ui.Button.ClickListener;

public class PersonForm extends Form implements ClickListener { private Button save = new Button("Save", (ClickListener) this); private Button cancel = new Button("Cancel", (ClickListener) this); private Button edit = new Button("Edit", (ClickListener) this); private AddressBookApplication app; public PersonForm(AddressBookApplication app) { this.app = app; // Enable buffering so that commit() must be called for the form // before input is written to the data. (Form input is not written // immediately through to the underlying object.) setWriteThrough(false); HorizontalLayout footer = new HorizontalLayout(); footer.setSpacing(true); footer.addComponent(save); footer.addComponent(cancel); footer.addComponent(edit); footer.setVisible(false); setFooter(footer); } public void buttonClick(ClickEvent event) { } }

Definir o formulrio para o modo de buffering (setWriteThrough (false)) significa que as alteraes feitas pelo usurio no atualizar imediatamente a fonte de dados. Em vez disso a fonte de dados atualizado quando commit() chamado para o formulrio. Podemos, ento, facilmente reverter os dados e obter o status antigo de volta chamando discard(). Isso precisa ser implementada no manipulador de clique no boto:public void buttonClick(ClickEvent event) { Button source = event.getButton(); if (source == save) { // If the given input is not valid there is no point in continuing if (!isValid()) { return; } commit(); setReadOnly(true);

} else if (source == cancel) { discard(); setReadOnly(true); } else if (source == edit) { setReadOnly(false);

} }

No podemos ainda testar a nossa forma como fizemos no rodap oculto para o formulrio padro ser vazio. Em seguida, vamos substituir dois mtodos: setItemDataSource() e setReadOnly() para fazer o trabalho da forma como queremos. As implementaes padro funcionam muito bem, mas queremos adicionar algumas tarefas adicionais para eles. O mtodo setItemDataSource() chamado quando a fonte de dados for alterado, por exemplo, quando o usurio seleciona uma pessoa na tabela. Neste ponto, quero fazer trs coisas: definir a forma a um estado de somente leitura chamando setReadOnly(true). Este o estado inicial. garantir que o rodap do formulrio visvel. Verifique se os campos so processados na ordem que quiser (de acordo com a tabela);

No mtodo setReadOnly() queremos controlar quais botes so mostrados no rodap. Salvar e Cancelar precisam estar visveis quando o formulrio no modo de edio e no boto Editar quando o formulrio em modo read-only. Chamando setItemDataSource() ir regenerar todos os campos dentro do formulrio de modo que este um bom lugar para contar a forma em que ordem queremos os campos a serem prestados. Nossos mtodos substitudo a seguinte aparncia:@Override public void setItemDataSource(Item newDataSource) { if (newDataSource != null) { List orderedProperties = Arrays .asList(PersonContainer.NATURAL_COL_ORDER); super.setItemDataSource(newDataSource, orderedProperties); setReadOnly(true); getFooter().setVisible(true); } else { super.setItemDataSource(null); getFooter().setVisible(false); }

}

@Override public void setReadOnly(boolean readOnly) {

super.setReadOnly(readOnly); save.setVisible(!readOnly); cancel.setVisible(!readOnly); edit.setVisible(readOnly); }

Implementando a lgica e adicionando novos contatos Em seguida, queremos criar novos contatos. A maior parte desta lgica vai para PersonForm mas devemos primeiro criar alguma lgica na classe principal do aplicativo. Antes de passar o controle para o PersonForm para a adio real queremos garantir que o ListView est sendo mostrado e queremos tambm para limpar todas as selees possveis da tabela. Adicionar mais lgica para o manipulador de clique em AddressBookApplication e fazer um clique no controle passam Adicionar contato boto para o mtodo addNewContact (). Implement-lo da seguinte forma:private void addNewContanct() { showListView(); personForm.addContact(); }

Em seguida, criamos o mtodo AddContact() em PersonForm. Agora o problema que no temos um objeto Pessoa existente para editar, mas precisa criar um temporrio. Tambm precisamos de uma bandeira que diz que estamos em "newContactMode" para que possamos adicionar a pessoa fonte de dados quando o usurio clicar em Salvar (no queremos para adicion-lo imediatamente, pois, ento, aparecer no PersonTable e, adicionalmente, teramos para remov-lo se o usurio clicar em Cancelar). Ns adicionamos dois campos de conseguir isso (poderia ser combinado, mas mantidos separados aqui para maior clareza):private boolean newContactMode = false; private Person newPerson = null;

Ento, ns instanciar uma pessoa nova, temporria e coloc-lo em forma, sem afetar a fonte de dados no aplicativo principal. Isto feito facilmente por envolvimento a pessoa em um cenrio que BeanItem e como fonte de dados para o formulrio. Ns no queremos apenas uma leitura vista ao adicionar um contato para que os nossos AddContact() mtodo ser parecido com este:public void addContact() { // Create a temporary item for the form newPerson = new Person(); setItemDataSource(new BeanItem(newPerson)); newContactMode = true; setReadOnly(false); }

Agora experimente clicar no boto Adicionar contato para garantir que tudo funciona to longe. Ainda estamos carentes de lgica adequada para a manipulao Salvar e Cancelar eventos para um novo contato. Ao salvar um novo contato do objeto Pessoa temporrio, ou realmente o BeanItem envolv-lo, deve ser adicionado nossa principal fonte de dados, o PersonContainer. Isso far com que o novo contato aparecem na tabela automaticamente. Se o usurio clicar em Cancelar ao

adicionar um contato devemos esvaziar o formulrio em vez de defini-la como modo de somente leitura. Com estas mudanas o nosso ouvinte clique na forma parecido com este:public void buttonClick(ClickEvent event) { Button source = event.getButton(); if (source == save) { if (!isValid()) { return; } commit(); if (newContactMode) { Item addedItem = app.getDataSource().addItem(newPerson); setItemDataSource(addedItem); newContactMode = false; } setReadOnly(true); } else if (source == cancel) { if (newContactMode) { newContactMode = false; setItemDataSource(null); } else { discard(); } setReadOnly(true); } else if (source == edit) { setReadOnly(false); } }

Finalmente, "newContactMode" tambm deve ser limpo quando selecionar uma nova linha na tabela sem clicar em Salvar ou Cancelar:public void setItemDataSource(Item newDataSource) { newContactMode = false; ... }

Implementando a funcionalidade de procura Temos adicionado previamente lgica para o boto de busca para uma viso da pesquisa exibido quando o boto na barra de ferramentas clicado, mas a viso ainda est vazio. Queremos criar uma viso simples onde voc pode digitar um termo de pesquisa, selecione o campo para coincidir com o termo e, opcionalmente, para salvar a pesquisa para uso posterior. A vista terminou deve ter a seguinte aparncia.

Vamos implementar isso usando um FormLayout que far com que as legendas a serem prestados esquerda dos campos em vez de acima (como o caso com um VerticalLayout). Alm do layout, precisamos de um par de TextFields, um NativeSelect, um CheckBox e um boto de pesquisa. O cdigo a seguir usado para criar o layout.package com.vaadin.demo.tutorial.addressbook.ui; import import import import import import import import import import com.vaadin.demo.tutorial.addressbook.AddressBookApplication; com.vaadin.demo.tutorial.addressbook.data.PersonContainer; com.vaadin.ui.Button; com.vaadin.ui.CheckBox; com.vaadin.ui.FormLayout; com.vaadin.ui.NativeSelect; com.vaadin.ui.Panel; com.vaadin.ui.TextField; com.vaadin.ui.Button.ClickEvent; com.vaadin.ui.Button.ClickListener;

public class SearchView extends Panel { private TextField tf; private NativeSelect fieldToSearch; private CheckBox saveSearch; private TextField searchName; private AddressBookApplication app; public SearchView(final AddressBookApplication app) { this.app = app; setCaption("Search contacts"); setSizeFull(); FormLayout formLayout = new FormLayout(); setContent(formLayout); tf = new TextField("Search term"); fieldToSearch = new NativeSelect("Field to search"); saveSearch = new CheckBox("Save search"); searchName = new TextField("Search name"); Button search = new Button("Search");

for (int i = 0; i < PersonContainer.NATURAL_COL_ORDER.length; i++) { fieldToSearch.addItem(PersonContainer.NATURAL_COL_ORDER[i]); fieldToSearch.setItemCaption(PersonContainer.NATURAL_COL_ORDER[i], PersonContainer.COL_HEADERS_ENGLISH[i]); } fieldToSearch.setValue("lastName"); fieldToSearch.setNullSelectionAllowed(false); saveSearch.setValue(true); addComponent(tf); addComponent(fieldToSearch); addComponent(saveSearch); addComponent(searchName); addComponent(search); } }

Todos os ids disponveis propriedade do PersonContainer so adicionados ao campo de escolha no loop for. No podemos usar o PersonContainer como fonte de dados para o campo, pois isso iria adicionar todas as pessoas para o drop-down, em vez das propriedades (cabealhos na tabela). O setItemCaption() define o que est sendo exibido para uma forma mais legvel, como os cabealhos da tabela. Queremos forar o usurio a selecionar um campo para busca de modo que defina nullSelectionAllowed para false, caso contrrio, o valor de um vazio seria adicionado ao selecionar (e isso seria selecionada por padro tambm). Tambm fazemos a suposio de que o usurio na maioria das vezes quiser salvar a sua pesquisa para a caixa de seleo savesearch marcada por padro (valor = true). Agora podemos executar o programa e o layout deve aparecer quando clicar no boto Search. H um pequeno problema, porm, nada acontece quando voc clique em Pesquisar. Ento, ns precisamos adicionar alguma lgica para a vista. Queremos acrescentar duas coisas: desmarcando a caixa de seleo savesearch deve esconder o searchName campo e clicar no boto de pesquisa devem realizar uma pesquisa. Escondendo o campo searchName quando desmarcando a caixa de seleo savesearch requer apenas algumas linhas de cdigo:saveSearch.setImmediate(true); saveSearch.addListener(new ClickListener() { public void buttonClick(ClickEvent event) { searchName.setVisible(event.getButton().booleanValue()); } });

Primeiro, precisamos definir o checkbox savesearch para o modo imediato assim que ns comeamos um evento cada vez que o usurio interage com ele. Em seguida, anexar um ouvinte clique para que possamos reagir a verificao de usurio ou desmarcando a caixa de seleo. Ns reagimos ao evento clique simplesmente definindo a visibilidade do campo searchName ao status checkbox (true se verificado, false se no for controlada). Realizar a pesquisa requer um esforo um pouco mais. Precisamos passar a entrada do usurio para o PersonList (tabela) para que ele possa filtrar o conjunto de resultados e mostrar apenas as linhas correspondentes. Alm disso temos necessidade de armazenar a busca se o usurio tiver marcado a caixa de seleo savesearch. Primeiro criamos uma classe de dados simples, SearchFilter, onde podemos armazenar a entrada do usurio.package com.vaadin.demo.tutorial.addressbook.data; import java.io.Serializable; public class SearchFilter implements Serializable { private final String term; private final Object propertyId; private String searchName; public SearchFilter(Object propertyId, String searchTerm, String name) { this.propertyId = propertyId; this.term = searchTerm; this.searchName = name; } }

Em seguida, adicionar um ouvinte clique para o boto salvar, que vai buscar o valor do campo de pesquisa e longo prazo, criar um SearchFilter e pass-la para a aplicao principal. Se savesearch foi verificada tambm dizer ao aplicativo para salvar a pesquisa.search.addListener(new Button.ClickListener() { public void buttonClick(ClickEvent event) { performSearch(); } });

Como o cdigo mais do que algumas linhas que adicion-lo como um mtodo separado:private void performSearch() { String searchTerm = (String) tf.getValue(); SearchFilter searchFilter = new SearchFilter(fieldToSearch.getValue(), searchTerm, (String) searchName.getValue());

if (saveSearch.booleanValue()) { app.saveSearch(searchFilter); } app.search(searchFilter); }

Agora precisamos adicionar a busca ea lgica savesearch para a classe de aplicao.public void search(SearchFilter searchFilter) { getDataSource().removeAllContainerFilters(); getDataSource().addContainerFilter(searchFilter.getPropertyId(), searchFilter.getTerm(), true, false); showListView(); }

O mtodo de busca simplesmente elimina qualquer filtro anterior e em seguida, adiciona um recipiente de filtro para a fonte de dados tabela utilizando os dados a partir do argumento searchFilter. Os parmetros verdadeiro e falso ao addContainerFilter () chamada liga ignoreCase e faz coincidir o termo como uma seqncia de sub (no s como prefixo, ou seja, ele ir procurar por "* prazo *", no "termo*").public void itemClick(ItemClickEvent event) { if (event.getSource() == tree) { Object itemId = event.getItemId(); if (itemId != null) { if (NavigationTree.SHOW_ALL.equals(itemId)) { getDataSource().removeAllContainerFilters(); showListView(); } else if (NavigationTree.SEARCH.equals(itemId)) { showSearchView(); } else if (itemId instanceof SearchFilter) { search((SearchFilter) itemId); } } } }

O savesearch() mtodo adiciona um novo item para a rvore, sob o n busca e em seguida, seleciona esse n:public void saveSearch(SearchFilter searchFilter) { tree.addItem(searchFilter); tree.setParent(searchFilter, NavigationTree.SEARCH); tree.setChildrenAllowed(searchFilter, false); tree.expandItem(NavigationTree.SEARCH); } tree.setValue(searchFilter);

O searchFilter usado como o itemId para o n de rvore. Uma rvore usa o mtodo toString() do itemId para determinar o que exibir para o usurio por padro (isto pode ser alterado por setItemCaptionMode()). Ns, portanto, temos a necessidade de implementar um mtodo toString() na nossa classe SearchFilter que retorna o que queremos mostrar para o usurio:@Override public String toString() { return getSearchName(); }

Usando o objeto como o searchFilter itemId na rvore torna mais fcil para adicionar no caso do itemClick() manipulador para a rvore de forma a pesquisa realizada toda vez que a pesquisa salva clicado. Faa o seguinte aditamento ao itemClick() manipulador no AddressBookApplication:public void itemClick(ItemClickEvent event) { if(event.getSource() == tree) { [...] } else if (itemId instanceof SearchFilter) { search((SearchFilter) itemId); } [...] }

Basicamente a aplicao e os primeiros passos para se desenvolver aplicativos utilizando o framework Vaadin so estes, com mais algumas alteraes, que sero disponibilizadas no cdigo e no livro Vaadin. Por titulo de curiosidade alguns cdigos, utis: Validao de dados do usurio:Field field = super.createField(item, propertyId, uiContext); if (propertyId.equals("postalCode")) { TextField tf = (TextField) field; tf.setNullRepresentation(""); tf.addValidator(new RegexpValidator("[1-9][0-9]{4}", "Cdigo Postal composto somente por digitos e no comea com zero")); tf.setRequired(true); }

Carregando Icones em botes:help.setIcon(new ThemeResource("icons/32/help.png"));

Criando uma conexo com o banco de dados, lembrando que existe diversas maneiras de realiz-la, no qual apenas demonstrarei uma delas:Properties p = new Properties(); p.put("user", username); p.put("password", password); p.put("port", 1433); p.put("password", password); DriverManager.registerDriver(new SQLServerDriver());

Connection connection= DriverManager.getConnection(url, p);

Realizando alguma query:PreparedStatement ps = connection.prepareStatement("INSERT INTO FormInput (field1, field2, user_id) values (?,?,?)"); ps.setString(1, value); ps.setString(2, value2); ps.setInt(3, user.getId()); ps.executeUpdate(); connection.commit();

Mapeando classes utilizando annotations:@Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.TABLE) private String id; private String name; @OneToMany private List jobList = new ArrayList(); public String getId() { return id; } public void setId(String Id) { this.id = Id; } public String geName() { return name; } public void setName(String name) { this.name = name; } public List getJobs() { return this.jobs; } public void setJobs(List jobs) { this.jobs = jobs; } }

Exemplo bsico de um insero de "linha" em uma tabela, e recuperando dados considerando a classe acima:

Person p = new Person(); p.setName("name"); entityManager.persist(p); person.getJobs();

Vaadin um poderoso framework, que possui diversas utilidades da qual foi abordada apenas aplicativos Web, onde hoje ele conta com diversas Api's, que do suporte no apenas para Web, mas tambm aplicativos mveis. Para maiores informaes acessem: https://vaadin.com/home