32
fevereiro 2014

The Club - megazine · Delphi XE5 – Banco de dados ... a utilizar Orientação a Objetos com Recursos ... Na tela seguinte será necessário escolher os objetos que serão mapeados,

  • Upload
    letruc

  • View
    250

  • Download
    8

Embed Size (px)

Citation preview

fevereiro2014

fevereiro2014

fevereiro2014 03

16

ndice

Desafio The Club

30

Editorial

04

11

Autor: Hamden Vogel

05

Autor: Joo Marcos Sakalauska

24Android - Personalizando o Spinner

Autor: Thiago C. Montebugnoli

Autor: Jeferson Silva de Lima

ASP.NET

Projeto Pegaso:

Delphi XE5 Banco de dados com Android

Aplicaes .NET em camadas, teoria e prtica - Parte 1

Projeto Pegaso Aprendendo a utilizar Orientao a Objetos com Recursos Multi-Plataforma Novas Tcnicas de Programao - Parte 2

fevereiro201404

Delphi marca registrada da Borland International, as demais marcas citadas so registradas

pelos seus respectivos proprietrios.

Thiago Montebugnoli - Editor [email protected]

Ol amigos do The Club!

Estamos aqui mais um ms deste ano de 2014, sempre com o intuito de agrad-los com o contedo de nossos artigos. A todo o momento estamos nos deparando com o desenvolvimento de novas tecnologias no ramo da programao. A nossa revista ir sempre procurar abranger um pouco destas inovaes. Para comear, nosso consultor tcnico Jeferson Silva de Lima, aborda mais um assunto englobando o Delphi XE 5 utilizando a plataforma Android, nos ensinando como conectar com Banco de Dados. Atravs de um exemplo prtico nos auxiliar com as configuraes iniciais. J nosso colaborador Joo Marcos Sakalauska redigiu um artigo seguido de um exemplo prtico de como devemos desenvolver Aplicaes .NET em camadas. Nesta primeira parte ele nos ensina um pouco da teoria seguido de um exemplo. Hamden Vogel finaliza o artigo Projeto Pegaso Aprendendo a utilizar Orientao a Objetos com Recursos Multi-Plataforma com novas Tcnicas de Programao. Nesta segunda e ltima parte podemos aliar o conhecimento de Programao Orientada a Objetos juntando com o desen-volvimento de um pequeno projeto para aprendizado. Para finalizar nossa srie de artigos, eu escrevi um pouco sobre o componente Spinner, um dos mais utilizados na plataforma Android. Utilizei a linguagem Java + XML para obter recursos diferentes e amigveis para o usurio final. Procurei tambm ajudar o programador demonstrando algumas tcnicas de criaes de estilos no formato .xml.

Para Finalizar a revista, no podemos esquecer nossa srie de Dicas e Truques.

Um grande abrao e at o ms que vem!

Av. Prof Celso Ferreira da Silva, 190 Jd. Europa - Avar - SP - CEP 18.707-150

Informaes e Suporte: (14) 3732-1529

Internethttp://www.theclub.com.br

Cadastro: [email protected]: [email protected] Informaes: [email protected] Cadastro: theclub_cadastro

Skype Suporte: theclub_linha1 theclub_linha2 theclub_linha3

www.twitter.com/theclubbr

Copyright The Club 2013

Diretor TcnicoMarcos Csar Silva

DiagramaoVitor M. Rodrigues

DesignVitor M. Rodrigues

RevisoDrielly Cristini Patrinhani

ColunistasHamden Vogel

Jeferson Silva de LimaLuciano Pimenta

Thiago Cavalheiro Montebugnoli

JuninhoJeferson Silva de Lima

Impresso e acabamento:GRIL - Grfica e Editora

Taquarituba-SP - Tel. (14) 3762-1345

ReproduoA utilizao, reproduo, apropriao, armazenamento em banco de dados, sob qualquer forma ou meio, de textos, fotos e outras criaes intelectuais em cada publicao da revista The Club Megazine so terminantemente proibidos sem autorizao escrita dos titulares dos direitos autorais.

Editorial

fevereiro2014 05

Atualmente muito comum ouvir a famosa expresso apli-caes em camadas ou desenvolvimento em camadas ou apenas camadas. Essa expresso no modismo, logo o conceito e o tipo de projeto em camadas (MVC) assumir de vez o lugar do WEBForms, ento, muito comum o assunto e voc pode facilmente v-lo aparecer numa entrevista de emprego, conversa com amigos de trabalho, faculdade, etc.

Ou seja, algo comum, muito comum mesmo, todo mundo fala.Mas a comea o problema, todo mundo fala, mas quem realmente conhece o suficiente para falar e fazer?

Por conta disso, resolvi apresentar esse assunto de duas formas, teoria e prtica. Ento, vamos comear pela parte terica conhecendoo conceito (resumido) do desenvolvimento de aplicaes em camadas.

Aplicaes em camadas (contexto histrico e terico)

Aplicaes monolticas So aplicaes antigas, escritas para rodar em uma nica mquina, que no contavam com recursos de rede como mostra a imagem 01. Essas aplicaes continham tudo em um nico lugar:

1. A camada de apresentao e entrada de informaes.2. Verificao e validao de regras de negcios.3. Banco de Dados.

Imagem 01 Banco de Dados, Regra de Negcios e apresentao contida num

Aplicaes .NET em camadas, teoria e prtica - Parte 1

nico lugar.

Essa estrutura pode parecer estranha, mas ainda existe, est em pleno funcionamento e mais prximo do que voc pensa, por exemplo: Sistema de Estacionamento.

Aplicaes em duas camadas Com a estrutura da organizao com-partilhando recursos por meio de rede e servidores, as aplicaes ganharam caractersticas de duas camadas conhecida como cliente/servidor. Nesse modelo, os dados ficam armazenados em segurana no servidor a disposio da aplicao conectada a rede como mostra a imagem 02.

Imagem 02 Estrutura Cliente/Servidor

Aplicao em trs camadas Com o crescimento da Internet houve a necessidade de estruturar melhor as aplicaes. Sendo assim, o MVC (Model, View, Controller) tem a proposta de separar camada de interface com usurio atravs da View, Camada de requisies atravs do Controller e a camada de Dados por meio do Model como mostra a imagem 03.

fevereiro201406

Listagem 1

Imagem 03 MVC Model, View, Controller.

Aplicaes em camadas Viso Geral

Agora que voc j tem uma ideia a respeito de camadas, vamos fixar alguns conceitos.

Tanto Layer com Tier, significam camadas em ingls. S que Tier refere--se estrutura fsica (hardwares, servidores, etc.) e Layer refere-se estrutura lgica. Daqui em diante o foco ser na camada Layer j que vamos tratar da organizao da estrutura do cdigo da aplicao.

Nota: Lembrando que ao falar de camadas, no caso desse artigo Layer, no necessariamente estou falando s sobre MVC ou algo extre-mamente especfico. A ideia aqui a apresentao de conceito para que voc tenha a base necessria a ponto de evoluir a sua aplicao seguindo uma base de informao existente.

O interessante no conceito de desenvolvimento em camadas que voc no est restrito a apenas trs camadas, voc pode dividir em mais camadas se seu projeto exigir. Na verdade, quanto mais voc dividir visando organizar, mais trabalho ter no comeo, porm, mais produtividade e organizao voc ter ao final do projeto e no perodo de evoluo e sustentao.

Na diviso em camadas lgicas, destacamos os principais itens:

User Interface/Presentation Trata-se da camada de apresentao para coleta e exibio de dados.

Business LogicLayer Trata-se da camada de lgica e regras de negcio intermediando requisies do usurio.

Data Access Layer Camada de dados responsvel pela execuo de transaes de envio e retorno de dados. No confundir com DAO (Data Access Objetct) com DAL (Data Access Layer).

DAO um padro de projeto,Implementa especificamente um objeto contido no contexto de DAL.

Aplicaes em camadas (contexto prtico)

A partir de agora, vamos focar no desenvolvimento para que ao final, possamos enxergar e entender tudo o que foi mostrado na parte terica.

Nossa aplicao ser um simples cadastro de usurios em MVC, ento, fique atento aos requisitos do sistema para que voc possa aplicar o estudo da mesma forma como est sendo passado nesse artigo.

Requisitos:

Visual Studio 2010SQL Sever 2008 (como teremos apenas uma tabela, no creio que haver

problemas caso voc use o 2005 ou 2012)Entity Framework.NET Framework 4.0ASP.NET MVC 2 Web Application (a verso em no influenciar no aprendi-

zado do contexto desse artigo, pois, o foco o conceito e no a apresentao do MVC no .NET)

Sendo assim, vamos iniciar o desenvolvimento do banco de dados na nossa aplicao.

Abra o Sql Server Management Studio e crie o banco de dados para nossa aplicao como mostra a imagem04.

Imagem 04 Criando o Banco de Dados da aplicao.

Em New Database o nome dadoa nossa base ser MVC, aps digitar o nome, clique em OK como mostra a imagem 05.

Veja a imagem 05.

Com o Banco de Dados criado, abra uma nova janela clicando em New Query e utilize o script CREATE TABLE a seguir:

CREATETABLE [Usuario]( [IdUsuario] [bigint] IDENTITY(1,1)NOTNULL, [NomeUsuario] [varchar](50)

fevereiro2014 07

Imagem 06 Script executado no Banco de dados MVC.

NOTNULL, [EmailUsuario] [varchar](50)NOTNULL, [Login] [nchar](15)NOTNULL, [Senha] [nchar](15)NOTNULL CONSTRAINT [PK_Usuario] PRIMARYKEYCLUSTERED( [IdUsuario] ASC)WITH ( PAD_INDEX=OFF, STATISTICS_NORECOMPUTE=OFF, IGNORE_DUP_KEY=OFF, ALLOW_ROW_LOCKS=ON, ALLOW_PAGE_LOCKS=ON)ON [PRIMARY])ON [PRIMARY]

Antes de rodar o comando, certifique-se de que o banco selecionado o MVC, como mostra a imagem 06.

Imagem 05 Banco de dados nomeado como MVC.

fevereiro201408

Listagem 2

Com o Banco de Dados e a Tabela criada, precisamos de pelo menos dois registros na tabela, conforme script a seguir:

INSERTINTO [Usuario]([NomeUsuario],[EmailUsuario],[Login],[Senha])VALUES(Joo Marcos,[email protected],jmsaka,12345)

INSERTINTO [Usuario]([NomeUsuario],[EmailUsuario],[Login],[Senha])VALUES(Aderbal Lacerda,[email protected],aderb,ABC)

Com os dados inseridos, podemos continuar a preparao da nossa aplicao.

No visual studio 2010, selecione o projeto ASP.NET MVC 2 Web Application e nomeie para MVCApp e clique em OK como mostra a imagem 07.

Imagem 07 - Projeto ASP.NET MVC 2 Web Application.

Repare como ficou a estrutura de pastas na Solution Explorer com as camadas Model, View, Controller como mostra a imagem 08.

Imagem 08 Model, View, Controller na composio do projeto MVCApp.

Com a estrutura padro esta-belecida, vamos utilizar o Entity Framework para mapear nossa tabela de usurios e prover o objeto e seus recursos que facilitaro nossa imple-mentao.

Para isso, realize as seguintes etapas:

V at a janela Solution Explorer, clique com o boto direito no projeto MVCApp e escolha Add -> New Item.

Na janela que se abrir Add New Item MVCApp selecione a opo Data em InstalledTemplates e

a primeira opo ADO.NET Entity Data Model e coloque o nome de MVC.edmx conforme imagem 08.

Veja a imagem 08.

Na janela que se abrir voc estar na etapa ChooseModelContents,

fevereiro2014 09

clique em GeneratefromDatabase (pois, nesse caso, j temos a tabela e a entidade do banco que ser reconhecida automaticamente) e em seguida clique em Next conforme imagem 09.

Imagem 09 opo GeneratefromDatabase selecionada.

Na etapa Chooseyour data Connection clique em New Connection e selecione Microsoft SQL Server e depois clique em Continue conforme imagens 10 e 11:

Imagem 10 Seleo de nova conexo clicando em New Connection

Imagem 11 Seleo do nosso DataSource Microsoft SQL Server

Em Connection Properties informe os dados(Server Name, Authentica-tionMode, Selectorenter a databasename) para acesso conforme imagem 12.

Imagem 12 Connection Properties

Imagem 08 incluso do Entity Data Model

fevereiro201410

Aps preencher os dados, testar a conexo e clicar em OK, a tela Entity Data Model dever estar preenchida conforme imagem 13.

Imagem 13 - Entity Data Model aps estabelecer conexo.

Na tela seguinte ser necessrio escolher os objetos que sero mapeados, no caso desse artigo somente a tabela Usurios como mostra a imagem 14.

Imagem 14 Seleo do objeto que ser mapeado.

Finalizando essa etapa e clicando em Finish, o arquivo MVC.edmx ser exibido como mostra a imagem 15.

Veja a imagem 15

Com o banco de dados definido e mapeado encerramos a primeira parte, onde o foco foi direcionado principalmente para questes tericas e preparao inicial da nossa aplicao.

A partir do prximo artigo, trataremos questes prticas do MVC atravs da aplicao de cadastro de usurios.

Concluso

O tema desenvolvimento em camadas muito interessante, porm deve ser tratado com cautela e deve ser muito praticado alm de estudado.

Tome muito cuidado com fruns de discusso, pois, tem muita gente falando besteira que pode atrasar seu aprendizado, pesquise o assuntoem fontes confiveis como MSDN e Macoratti, por exemplo.

No tenha pressa em aprender s pra dizer que conhece, pois, experincia vale mais que conhecimento.

Fontes:http://pt.wikipedia.org/wiki/Modelo_em_tr%C3%AAs_camadasMicrosoft Visual C# 2008 - John Sharp

Imagem 15 Arquivo MVC.edmx gerado.

[email protected]

Joo Marcos Sakalauska31 anos, Analista de Sistemas e atua a mais de 10 anos na rea de

TI. Atualmente Lder Tcnico e Analista de Sistemas na IN3 Software atuando em projetos que utilizam as tecnologias .NET e Sql Server.

Sobre o autor

fevereiro2014 11

Quando desenvolvemos uma aplicao na plataforma An-droid temos em mente que nossa base de dados conven-cional no pode ser acessada diretamente pelo dispositivo mvel, ou seja, deve haver uma ponte entre o dispositivo e a base de dados.No artigo anterior vimos como acessar a base de dados Firebird atravs

do dispositivo Android utilizando o DataSnap em uma aplicao VCL, ou seja, nossa aplicao VCL foi a ponte entre os dados e o Android.

No entanto, caso o usurio necessite utilizar o dispositivo em locais exter-nos sem depender de outra aplicao temos que utilizar um banco compatvel com a plataforma, sem depender de DLL ou arquivos de configurao, veremos neste artigo como realizar a configurao para conectarmos diretamente na base de dados.

Conectando ao Banco

Neste exemplo utilizaremos o banco de dados SQLite que compatvel com a plataforma Android, alm do Interbase.

Para manipulao e gerenciamento dos dados podemos utilizar a ferra-menta SQLiteExpress que possui uma verso gratuito para testes.

No artigo publicado em Janeiro de 2012, podemos acompanhar a utilizao da ferramenta.

Android- Carregando um Database do SQLite:http://theclub.com.br/Restrito/Revistas/PDFS/2012/1201.pdf

Caso a utilizao da ferramenta no seja vivel o desenvolvedor pode criar sua base de dados atravs do Delphi, para isto v em DataExplorer/SQLite e adicione uma nova conexo. Nas configuraes indique o local que deseja criar o arquivo, exemplo:

C:\Users\Suporte4\Documents\meubanco.db

Delphi XE5Banco de dados com Android

Imagem 1 Configuraes da Conexo.

A extenso do arquivo ser (.db). Com o local indicado clique no boto Advanced e v at a propriedade FailifMissing marcando como False, assim ao tentar conectar ao banco se no existir ele ser criado, caso deixe True o Delphi apenas ir se conectar a base de dados.

Imagem 2 Propriedades avanadas.

fevereiro201412

Componentes

Aps configurarmos a conexo devemos criar as tabelas, para isso clique com o boto direito em Table em sua conexo e ter a opo New Table.

Imagem 3 Adicionando Tabela.

Imagem 4 Criao da Tabela.

Com a base de dados criada podemos prosseguir com as configuraes no Delphi.

Criando a aplicao

Adicione um SQLConnection ao formulrio e conecte a sua base de dados, coloque tambm um SQLDataSet, um ListView e 2 SQLQuery para tratarmos as inseres e delees do banco de dados.

Imagem 5 SQLConnection.

Nomeie os componentes conforme listagem abaixo:

SQLConnection1: Conexao; SQLQuery1: SQLInsert; SQLQuery2: SQLDelete; SQLDataSet1: sdsClientes;

No sdsClientes vamos trazer o campo CLI_NOME criado em nossa tabela e para exibi-lo em nosso ListView clique com o boto direito sobre o formulrio ou qualquer componente e v na opo Bind Visually, uma janela ser exibida conforme imagem abaixo:

Imagem 6 Bind Visually.

Ligue o campo CLI_NOME ao Item.Text do ListView para exibir os dados na lista. Para finalizarmos o Layout do formulrio adicione 2 Buttons e coloque a propriedade Text do primeiro boto como Novo e do segundo como Delete. Seu formulrio ir ficar parecido com a seguinte Imagem:

Imagem 7 Formulrio Principal.

Agora para adicionar a base de dados criada ao compilador de nosso Android v em:

fevereiro2014 13

Listagem 1 BeforeConnect.

Project/Deployment, conforme imagem abaixo:

Imagem 8 Deployment.

Clique em Add Files para selecionar sua base de dados.

Imagem 9 Add Files.

Aps ter adicionado o banco ele ser exibido na lista, ento altere a opo

Plataforms para Android e em Remote Path coloque: .\assets\internal (sem as aspas) , esse ser o local onde ficar nossa base de dados no dispositivo.

Imagem 10 Arquivo db.

Por fim v em seu SQLConnection e no evento BeforeConnect coloque o seguinte comando:

Conexao.Params.Values[Database] := TPath.Combine(TPath.GetDocumentsPath, nomedobanco.db);

Para utilizarmos a funo TPath adicione na uses System.IOUtils, feito isso execute o projeto. Os dados que esto em sua base de dados sero exibidos.

Imagem 11 Emulador.

Para manipularmos os dados utilizaremos os comandos de Insert e Delete, para isso vamos utilizar os componentes SQLQuery.

Conecte o SQLInsert ao Conexao e em parmetros (Params) adicione um campo conforme imagem abaixo:

fevereiro201414

Listagem 2 Comando Insert.

Listagem 3 Comando Delete.

Listagem 4 Boto Novo.Listagem 5 Boto Delete.

Imagem 12 Parmetro CLI_NOME.

Imagem 13 Parmetro.

Crie o parmetro da mesma forma no SQLDelete.

Na propriedade SQL do SQLInsert insira o seguinte comando:

INSERT INTO TAB_CLIENTE (CLI_NOME) VALUES (:CLI_NOME)

Na propriedade SQL do SQLDelete insira o comando:

DELETE FROM TAB_CLIENTE WHERE CLI_NOME = :CLI_NOME

Por ltimo vamos configurar o comando dos 2 botes que adicionamos anteriormente, comeando pelo boto Novo no evento OnClick coloque conforme listagem abaixo:

Var S: String;

begin Try if InputQuery(Novo Cliente,Nome,S) and (S.Trim ) then Begin SQLInsert.Close; SQLInsert.ParamByName(CLI_NOME).AsString := S; SQLInsert.ExecSQL(); sdsClientes.Refresh; End; except on e: Exception do begin ShowMessage(e.Message); end End;

Veja que utilizamos o InputQuery para capturar o valor digitado pelo usurio e passamos para o parmetro criado dentro do SQLInsert. Veja na imagem abaixo como ir ser exibido no Android:

Imagem 14 InputQuery Insert.

Agora vamos configurar o boto Delete, veja abaixo listagem com a codificao:

Var S: String;

fevereiro2014 15

begin S := ListView1.Selected.Text; Try if InputQuery(Deletar Cliente,Nome,S) and (S.Trim ) then Begin SQLDelete.Close; SQLDelete.ParamByName(CLI_NOME).AsString := S; SQLDelete.ExecSQL(); sdsClientes.Refresh; End; except on e: Exception do begin ShowMessage(e.Message); end End;

Veja que ao clicar no item da Lista ele ser armazenado na varivel S, veja na imagem abaixo:

Imagem 15 InputQuery Delete.

Concluso

Vimos neste artigo como conectar nosso dispositivo mvel na base de dados SQLite sem depender de outra aplicao, ou seja, tudo de forma sim-ples e direta. Este exemplo pode ser melhorado e implementado da forma que desejarem.

Espero que tenham gostado desta dica e at a prxima!

[email protected]

Jeferson Silva de LimaConsultor The Club.

Sobre o autor

fevereiro201416

Figura 17 Criao e Destruio da classe TPessoaFisica mtodos Create/Destroy.

Figura 18 Explanao das funes GetNextId (TConexaoDBISAM), GetCurren-tCod_Pessoa (TPessoaFisica) e GetFieldsFromSQL (TConexaoDBISAM).

Nesta segunda e ltima parte do artigo abordarei mais alguns recursos de nosso projeto. Seguindo a lgica de raciocnio, a nossa classe sempre dever se interagir com a TConexao para prover o banco de dados desejado. Para isso, a nossa classe de exemplo TPessoaFisica ter uma varivel privada de TConexao, que ser referenciada na classe inteira, para de forma abstrata prover este acesso.

Inicializado na construo da nossa classe de exemplo TPessoaFisica com o parmetro default (DBISAM), a varivel interna Conexao ser referenciada com o mtodo padro de construo GetConexao. Abaixo segue os cdigos de criao e destruio, respectivamente.

constructor TPessoaFisica.Create(const fbdConexao: tAliasBDConexao = (bdConexaoDBISAM); const _myForm: TForm = nil);begin if Assigned(_myForm) then MyForm := _MyForm; Conexao := Conexao.GetConexao(tBDConexao(fbdConexao));end;

destructor TPessoaFisica.Destroy;begin inherited; Conexao.closeConexao;end;

Uma coisa interessante a ser notada que algumas funes retornam o

tipo TFields, facilitando o retorno das chamadas de um dataset como se a

Projeto Pegaso Aprendendo a utilizar Orientao a Objetos com Recursos Multi-Plataforma Novas Tcnicas de Programao - Parte 2

prpria classe estivesse dentro do dataset em execuo isso prtico para o desenvolvedor medida em que evolui no cdigo-fonte, incrementando a produtividade do projeto e a elegncia do nvel do fonte tambm podendo retornar qualquer tipo includo na unit DB.pas por exemplo (um descendente de TCollection/ TOwnedCollection), ou ento customizando para novos tipos: observe abaixo a funo de retornar o prximo ID de uma tabela declarado como GetNextId de TConexaoDBISAM e TConexaoFirebird, respectivamente:

function TConexaoDBISAM.GetNextId(const fFieldName: string; const fTable: string): string;var fId: string;begin fId := TDBISAMQuery(Self.RetornaDataSet(Format(sqlMaxIndexFromFieldNameFormat2, [fFieldName, fTable]))).Fields[0].AsString; if (fId = ) then fId := 1; Result := fId;end;

function TConexaoFirebird.GetNextId(const fFieldName: string; const fTable: string): string;var fId: string;

fevereiro2014 17

Figura 19 Demonstrao do mtodo CarregarBanco nas classes TConexao-DBISAM e TConexaoFirebird.

begin fId := TCustomSQLDataSet(Self.RetornaDataSet(Format(sqlMaxIndexFromFieldNameFormat1, [fFieldName, fTable]))).Fields[0].AsString; if (fId = ) then fId := 1; Result := fId;end; if (Result = 1) then FCod_Pessoa := FormatFloat(0000, Self.GetCurrentCod_Pessoa);

function TPessoaFisica.GetCurrentCod_Pessoa: integer;begin Result := Conexao.GetFieldsFromSQL(Format(sqlSelectPessoaFisicaFromNome, [FNome])).Fields[0].AsInteger;end;

function TConexao.GetFieldsFromSQL(const fSQL: string): TFields;begin if Self is TConexaoDBISAM then Result := TConexaoDBISAM(Self).GetFieldsFromSQL(fSQL) else if Self is TConexaoXML then Result := TConexaoXML(Self).GetFieldsFromSQL(fSQL) else if Self is TConexaoFirebird then Result := TConexaoFirebird(Self).GetFieldsFromSQL(fSQL);end;

Um mtodo que no foi explicado ainda o CarregarBanco, presena obrigatria em todas as classes que descendam de TConexao pois ele o encarregado de procurar o banco de dados, e se encontrar, preparar ele (configurando permisses, drivers de acesso, etc) e deix-lo disponvel para as transaes que possam ser requeridas posteriormente. Esse mtodo deve ser chamado na criao do objeto de TConexao desejado (construtor de TCone-xaoDBISAM/ TConexaoFirebird, por exemplo). Segue abaixo as declaraes de CarregarBanco nas classes TConexaoDBISAM e TConexaoFirebird, bem como as suas chamadas no mtodo construtor de cada uma delas:

constructor TConexaoDBISAM.create;begin if (ffDiretorioDBISAM = ) then Self.CarregarBanco(DBISAM) else Self.CarregarBanco(ffDiretorioDBISAM); inherited;end;

function TConexaoDBISAM.CarregarBanco(const cDiretorio: string): Boolean;var fIniFile: TIniFile; fFile: TextFile; fPathCfgIni: string; fDiretorio: string; fNotOK: Boolean;begin fNotOK := False; fPathCfgIni := ExtractFilePath(Application.ExeName)+ FCFGIni;

dmDBISAM := TdmDBISAM.Create(nil); dmDBISAM.BD.Connected := False; if dmDBISAM.BD.DatabaseName = EmptyStr then dmDBISAM.BD.DatabaseName := FDataBaseName;

if not SysUtils.FileExists(fPathCfgIni) then begin AssignFile(fFile, fPathCfgIni); Rewrite(fFile); Append(fFile); Writeln(fFile, [Configuracao]); Writeln(fFile, Diretorio= ); Flush(fFile); { ensures that the text was actually written to file } CloseFile(fFile); end else begin fIniFile := TIniFile.

fevereiro201418

Create(fPathCfgIni); with fIniFile do begin try dmDBISAM.BD.Directory := ReadString(Configuracao, Diretorio, dmDBISAM.BD.Directory); dmDBISAM.BD.Connected := Self.BancoExiste(dmDBISAM.BD.Directory); finally Free; end; end; end;

if not (dmDBISAM.BD.Connected) then begin if Self.BancoExiste((ExtractFilePath(Application.ExeName) + BD\ + cDiretorio) , False) then //tenta achar localmente begin fIniFile := TIniFile.Create(fPathCfgIni); with fIniFile do begin try WriteString(Configuracao,Diretorio, (ExtractFilePath(Application.ExeName) + BD\ + cDiretorio)); finally Free; end; end; end else if not DirectoryExists(dmDBISAM.BD.Directory) or (dmDBISAM.BD.Directory = ) or not (dmDBISAM.BD.Connected) then begin fIniFile := TIniFile.Create(fPathCfgIni); with fIniFile do begin try WriteString(Configuracao,Diretorio, fDiretorio); finally Free; end; end; end else fNotOK := True;

end; //end if bd.connected = false then

if fNotOK then begin Result := False; end else begin if not (dmDBISAM.BD.Connected) then begin fIniFile := TIniFile.Create(fPathCfgIni); with fIniFile do begin try dmDBISAM.BD.Directory := ReadString(Configuracao, Diretorio, dmDBISAM.BD.Directory); dmDBISAM.BD.Connected := Self.BancoExiste(dmDBISAM.BD.Directory, False); finally Free; end; end; end; end; Result := not fNotOK;end;

{ TConexaoFirebird }

function TConexaoFirebird.CarregarBanco(const cDiretorio: string): Boolean;begin Result := True; if (cDiretorio = EmptyStr) then begin fVendorLib := FMyGDSVendorLib; fLibraryName := FMyDBXExpress FirebirdLibraryName; fPathDataBase := FUsuariosFDB; end else if (cDiretorio = default) then begin fVendorLib := FMyGDSVendorLib; fLibraryName :=

fevereiro2014 19

ExtractFilePath(Application.ExeName) + IncludeTrailingPathDelimiter(BD\FIREBIRD) + FMyDBXExpress FirebirdLibraryName; fPathDataBase := ExtractFilePath(Application.ExeName) + IncludeTrailingPathDelimiter(BD\FIREBIRD) + fPathDataBase; end else begin fVendorLib := cDiretorio + FMyGDSVendorLib; fLibraryName := cDiretorio + FMyDBXExpress FirebirdLibraryName; fPathDataBase := cDiretorio + fPathDataBase; end;

Result := ( (DirectoryExists(fPathDataBase)) and (FileExists(fLibraryName)) ); if not Result then Exit;

if not BancoInstanciado then dmFirebird := TdmFirebird.Create(nil);

try try with dmFirebird.SQLConnection do begin Connected := False; VendorLib := dbVendorLib; LibraryName := dbLibraryName; Params.Values[Database] := fPathDataBase + FUsuariosFDB; end; finally dmFirebird.SQLConnection.Connected := True; // dmFirebird.SQLTableUsuario.Open; with dmFirebird.SQLQuery do begin if Text EmptyStr then Open; end;

end; except on E: Exception do begin Raise EInvalidDataBase.Create(EErroGeralBancoDeDados + #13#10 + E.Message); Result := False; end; end;end;

constructor TConexaoFirebird.create(const cDiretorio: string = default);begin if not Self.CarregarBanco(cDiretorio) then Exit; inherited create;end;

Implementando a Interface IFrame Criao Dinmica de Frames em Tabsheets:

Interfaces so classes abstratas definem apenas as declaraes de mtodos que so funes, procedimentos e propriedades (nesta ltima os mtodos getters/setters tambm devem ser definidos). Em uma interface no h escopo de pblico, privado, protegido, etc justamente pelo fato de tudo ser pblico. Uma interface tambm no define variveis. O que uma interface faz? Nada. Ela define apenas o que as classes que descendam dela deva ser feito. uma abstrao na Linguagem Orientada a Objetos toda classe que interagir com ela (descendendo dela) dever obrigatoriamente declarar e construir seus mtodos no seu cdigo. Toda interface tem um valor chamado GUID (Globally Unique IDentifier - definido em um Record TGuid unit System tamanho 128-bit integer 16 bytes) que um valor nico referenciado nela. Para obter manualmente este valor GUID, basta pressionar Ctrl+Shift+G na IDE do Delphi.

Portanto, em uma interface no haver nenhuma implementao as outras classes que herdarem dela so as que implementaro o cdigo cor-respondente.

Segue abaixo alguns cdigos relativos utilizao da nossa interface cha-mada IFrame (declarada na unit UnFrames, onde tambm possui algumas funes instanciadoras e manipuladoras de objetos do tipo Frame e sua inte-rao com a interface citada, alm de manipular o carregamento e destruio desses objetos em contineres Tabsheet tudo isso realizado em execuo para inicializar o frame a ser carregado basta associar a propriedade tag do Ta-bsheet com a o frame a ser criado ex: tabHistorico.Tag := integer(TfrmEditor); perceba que queremos exibir o nosso frame no momento (evento) da exibio do Tabsheet em outras palavras nos eventos onShow/OnHide:

fevereiro201420

Listagem 20

type IFrame = interface [{112D577F-BA1B-4CAA-97D6-A12D25E6503B}] procedure OnShow; procedure OnHide; procedure Novo; procedure Persistir; procedure Excluir; procedure GetUsedClass(const fObject: TObject = nil); end;

procedure TfrmCadastroPessoaFisica.tabHistoricoShow(Sender: TObject);begin if Assigned(PessoaFisica) then GetActionFrame(PageControl1, Sender as TTabSheet, foShow, PessoaFisica);end;

procedure TfrmCadastroPessoaFisica.tabHistoricoHide(Sender: TObject);begin GetActionFrame(PageControl1, Sender as TTabSheet, foHide);end; function GetFrame(APageControl: TPageControl; ATabSheet: TTabsheet): TFrame;begin if not Assigned(ATabsheet) then ATabsheet := APageControl.ActivePage; Result := nil; if Assigned(ATabsheet) and (ATabSheet.ControlCount > 0) and (ATabSheet.Controls[0] is TFrame) then Result := TFrame(ATabSheet.Controls[0]);

end;

procedure DestroyFrame(APageControl: TPageControl; ATabsheet: TTabsheet);var frame: TFrame;begin frame := GetFrame(APageControl, ATabsheet); if frame nil then frame.Free; end;

function GetActionFrame(APageControl: TPageControl; ATabsheet: TTabSheet; AFrameOption: FrameOption; const myObject: TObject = nil): TFrame;var intf: IFrame; frame: TFrame;begin Result := nil;

CreateFrame(APageControl, ATabsheet);

frame := GetFrame(APageControl, ATabsheet);

if not Supports(frame, IFrame, intf) then Exit;

case AFrameOption of foShow: begin if Assigned(myObject) then intf.GetUsedClass(myObject); intf.OnShow; end; foHide: intf.OnHide; end;

Result := frame;end;

fevereiro2014 21

Figura 20 Criao do objeto do tipo TFrame na tabsheet de Histrico em tempo de execuo.

Figura 21-24 Exibio das principais Telas do nosso sistema em execuo a ltima a janela-dilogo de confirmao de excluso personalizada pelo componente sha-reweare TAdvSmoothMessageDialog da empresa TMSSoftware.

fevereiro201422

Figura 21-24 Exibio das principais Telas do nosso sistema em execuo a ltima a janela-dilogo de confirmao de excluso personalizada pelo componente shareweare TAdvSmoothMessageDialog da empresa TMSSoftware.

fevereiro2014 23

Concluso

Foram discutidos tpicos relacionados a Linguagem Orientada a Objetos em Delphi atravs de um exemplo fictcio mas de implementao profissional de um sistema em desenvolvimento abordando a criao da classe negocial de Pessoa Fsica, a classe TConexao e suas comunicaes, bem como a criao do banco de dados e a camada de apresentao correspondente. Foi abordado novo template de telas personalizado com efeitos suaves, gradientes, leves e agradveis customizados por componentes de terceiros e com design diferenciado de certos componentes (como panis com bordas arredondadas, panis com gradiente de barras de ferramentas e ttulos nas posio top/left no estilo Microsoft/XP) e outras tcnicas de implementao como a utilizao de interfaces com frames e a classe TConexao projetada para ambientes multiplataforma.

Com isso, foi distribudo este projeto de teste para acompanhamento de como foi desenvolvido (a partir do cdigo-fonte) e como foi desenhado (a partir das telas em tempo de execuo) onde um usurio final poder exe-cutar o aplicativo em qualquer diretrio de seu computador (da maneira que foi distribudo os fontes pelo artigo) e perceber o funcionamento do mesmo.

Portanto, espero que a concepo deste projeto, desde sua idealizao at a entrega inicial destes fontes, banco de dados e executvel possa servir de inspirao, aprendizado, refinamento e novas idealizaes de novos projetos

que venham a contribuir com todos os desenvolvedores Delphi esta incrvel ferramenta de programao que sempre se encontra cada vez mais imbatvel e poderosa frente novas IDEs que surgem no mercado diariamente tambm aliadas a novas formas alternativas de formatos de trocas de informaes como JSON, etc.

Um abrao a todos e at aos prximos artigos! At l!

[email protected]

Hamden VogelAnalista de Sistemas ps-graduado em Engenharia de Software pela

UPIS e Programador Delphi com larga experincia desde 2000, tem de-senvolvido e vendido softwares em Delphi para a frica e Estados Unidos, alm do mercado nacional. Colaborou com dicas e componentes para sites especializados em Delphi. Tambm desenvolve em outras linguagens como C/C++, ASP, PHP e .NET.

Sobre o autor

fevereiro201424

Listagem 01: Classe Cidades.java.

Muitas vezes temos a necessidade de personalizar com-ponentes ao decorrer do desenvolvimento de algum projeto. Na realidade isto que deixa nosso software com um lay-out diferente dos outros. Quando traba-lhamos com a programao para Android inevitvel no nos deparar com uma situao destas. Neste artigo irei personalizar um dos principais componentes, o Spinner. Ele fornece uma maneira rpida de selecionar um valor a partir de um conjunto de valores. No estado padro, um Spinner mostra seu valor atualmente selecionado. Ao selecion-lo exibido um Menu suspenso com todos os outros valores disponveis, a partir do qual o usurio pode selecionar um novo. Ele se parece com o Combobox do Delphi ou o DropDownList da plataforma .Net.

Ento chega de conversa e vamos por a mo na massa.

Criando um Exemplo Prtico

importante sabermos que para efetuarmos formataes de tamanho, cor ou estilos em geral deste tipo de componente exige configuraes dife-renciadas, para isto devemos criar um arquivo especfico (XML) prprio para cada tipo de configurao. Para fins didticos, o exemplo se dividir em 3 (trs) etapas, sendo:

1-) Personalizao geral do componente;2-) Personalizao do Item do componente;3-) Personalizao para insero de imagem no item do componente.

O primeiro passo seria criar a Atividade Principal clicando no menu File/New/Android Application Project para criar um novo projeto. Na Tabela 1 esto as principais configuraes.

Propriedade Valor DescrioActivity Name MainActivity Nome da Atividade

Layout Name Activity_main Nome do Layout

Navigation Type None Tipo de navegaoTabela 1. Configuraes Iniciais do Projeto.

Classe Cidades.java

Devemos tambm programar uma classe padro que ir nos retornar um Conjunto de valores. No caso nesta classe foram cadastradas algumas cidades de exemplo.

Veja abaixo o cdigo da classe Cidades.java.

package com.example.android_spinner;

import java.util.ArrayList;

public class Cidades{ public ArrayList RetornarCidades; public Cidades() { RetornarCidades = new ArrayList(); RetornarCidades.add(AVAR); RetornarCidades.add(BOTUCATU); RetornarCidades.add(CERQUEIRA CSAR); RetornarCidades.add(FARTURA); RetornarCidades.add(ITATINGA); RetornarCidades.add(ITA); RetornarCidades.

Android - Personalizando o Spinner

fevereiro2014 25

Listagem 02: XML da tela principal.

add(PIRAJU); RetornarCidades.add(SO PAULO); }}

A funo desta classe nos retornar um ArrayList dos valores cadastrados no mtodo Construtor. Veremos mais adiante sua utilizao.

Activity_Main.xml

O rosto principal do exemplo ser composto por 3 (trs) Componentes Spinners. Ver Imagem 01.

Figura 01: Activity_Main.xml.

O cdigo XML correspondente: (Listagem 02)

fevereiro201426

Listagem 03: Cdigo XML do Spinner_theclub.

Listagem 04: Cdigo XML do Spinner_dropdown_theclub.

Listagem 05: Cdigo XML do Spinner_imagem_theclub.

below=@+id/spinner2 android:layout_marginTop=58dp />

1-) Personalizao geral do componente

Para criar o arquivo XML clique com o boto direito sobre o caminho ../res/layout escolhendo a opo New/Other/Android XML File. Ver Imagem 02.

Figura 02: Criando o arquivo de configurao.

Defina o nome para o arquivo como: spinner_theclub.xml (Este ser o nome utilizado como referncia mais adiante) Adicionaremos o cdigo para aumentar o tamanho da fonte para 30sp (textSize) e definirmos a cor para Vermelho (textColor). Note que estamos trabalhando como referncia um componente do tipo TextView, ou seja, todos os atributos desta classe sero encapsulados para em seguida implementarmos no Spinner. Listagem 03.

2-) Personalizao do Item do componente

Devemos seguir os mesmos passos descritos anteriormente, a diferena deste que definiremos outro nome para o arquivo, como: spinner_dropdo-wn_theclub.xml e utilizaremos alguns atributos da classe CheckedTextView. Os principais so: singleline (Itens do Spinner com apenas uma linha) e textColor (Cor da Fonte). Ver Listagem 04.

3-) Personalizao para insero de imagem no item do componente

Por padro, quando criamos um novo projeto no Android temos uma imagem chamada ic_launcher.png localizada no diretrio Drawable. Utili-zaremos esta para fins de aprendizado. Teremos que utilizar o TableLayout seguido de uma TableRow(Atravs destes componentes que conseguiremos concatenar dois tipos de valores). Dentro dele utilizaremos uma classe Ima-geView para recuperarmos a imagem outra TextView para atribuirmos os valores. Dentro desta segunda classe primordial utilizar as propriedades Text e Id, pois a partir delas que interligamos nossas configuraes mais adiante. Ver Listagem 05 para melhores detalhes.

fevereiro2014 27

tableRow1 android:layout_width=wrap_content android:layout_height=wrap_content android:padding=10px>

Ao trmino o projeto ter a seguinte estrutura, Ver Imagem 03.

Figura 03: Arquivos do Exemplo.

MainActivity.java

Para cada exemplo achei melhor criar um Procedimento. O projeto ser dividido em 4 (quatro) Procedimentos, sendo:

- InicializaListeners(): Responsvel por inicializar os componentes Spin-ners e o objeto Cidades.

- ValorPersonalizado(): Personalizar os valores gerais do Spinner. (Spin-ner_theclub.xml)

- ItemPersonalizado(): Personalizar especificamente os itens do Spinner. (Spinner_dropdown_theclub.xml)

- ImagemItemPersonalizado(): Utilizar uma imagem no Spinner. (Spin-ner_imagem_theclub.xml)

package com.example.android_spinner;

Utilizaremos algumas bibliotecas adicionais para desenvolver este exem-plo, veja abaixo:

import java.util.ArrayList;import java.util.HashMap;import android.os.Bundle;import android.app.Activity;import android.widget.ArrayAdapter;import android.widget.SimpleAdapter;import android.widget.Spinner;

public class MainActivity extends Activity { private Spinner spn1, spn2,spn3; private Cidades cidades;

Criamos 3 (trs) variveis privadas do tipo Spinner e outra para a classe Cidades.

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); InicializaListeners(); ValorPersonalizado();

fevereiro201428

ItemPersonalizado(); ImagemItemPersonalizado(); }

No mtodo OnCreate() onde invocaremos os procedimentos descritos anteriormente.

public void InicializaListeners() { spn1 = (Spinner) findViewById(R.id.spinner1); spn2 = (Spinner) findViewById(R.id.spinner2); spn3 = (Spinner) findViewById(R.id.spinner3); cidades = new Cidades(); }

Como o prprio nome j diz, inicializamos todas as variveis declaradas anteriormente com o mtodo FindViewById.

public void ValorPersonalizado() { ArrayAdapter arrayAdapter1 = new ArrayAdapter(this,R.layout.spinner_theclub, cidades.RetornarCidades); spn1.setAdapter(arrayAdapter1); }

A Classe ArrayAdapter receber a lista de cidades cadastradas na classe Cidades junto com as configuraes. O primeiro parmetro o Contexto da aplicao, o segundo seria o XML criado por ns ( neste exato momento que nosso Spinner assumir o formato que desejamos) e o ltimo valor seria a lista de cidades. Definimos para o componente usando o mtodo setAdapter. Ver Imagem 04.

Figura 04: Mtodo ValorPersonalizado().

public void ItemPersonalizado() { ArrayAdapter arrayAdapter2 = new ArrayAdapter(this,R.layout.spinner_theclub, cidades.RetornarCidades); arrayAdapter2.setDropDownViewResource(R.layout.spinner_dropdown_theclub); spn2.setAdapter(arrayAdapter2); }

Nesta funo teremos como base o item anterior, personalizando o valor e o item selecionado. O mtodo setDropDownViewResource() ir carregar o arquivo de configurao spinner_dropdown_theclub. Ver Imagem 05.

fevereiro2014 29

Figura 05: Mtodo ItemPersonalizado().

public void ImagemItemPersonalizado() {ArrayList alist = new ArrayList();HashMap map = new HashMap(); for(int i=0; i < cidades.RetornarCidades.size(); i++) { map = new HashMap();map.put(Cidades, cidades.RetornarCidades.get(i).toString()); alist.add(map); } SimpleAdapter simpleAdapter = new SimpleAdapter(this, alist,R.layout.spinner_imagem_theclub, new String[] {Cidades}, new int[] {R.id.SpinnerCidadeItem}); spn3.setAdapter(simpleAdapter); }}

Para inserirmos uma imagem no Spinner, teremos um trabalho a mais para fazer. Primeiramente devemos declarar um ArrayList utilizando o tipo de dados HashMap. Quando utilizamos este tipo devemos obrigatoriamente informar o par chave/valor. Para preencher os itens do Spinner faremos um lao e em seguida usar a classe SimpleAdapter contendo os parmetros: - Contexto da aplicao, - o Arraylist com os campos chave/valor, - o arquivo de configurao spinner_imagem_theclub.xml, a chave Cidades e por final o SpinnerCidadeItem contido no arquivo de configurao (Nesta referncia onde ser armazenada os dados oriundos do ArrayList). Ver Imagem 06.

Figura 06: Mtodo ImagemItemPersonalizado().

Concluses

A linguagem Java + XML nos proporciona diversos tipo de recursos no desenvolvimento de aplicativos para a plataforma Android. Neste artigo, achei necessrio explorar um pouco mais deste componente, o Spinner. O Spinner um dos componentes mais utilizados quando precisamos retornar dados de diversas fontes (Neste artigo usamos uma classe com dados estticos para esta tarefa). Pudemos enfeitar e deixar com uma aparncia muito mais agradvel alterando tamanho e cor de fontes, Imagens, estilos, entre outras coisas. Vou ficando por aqui, Abraos e at o ms que vem!

[email protected]

Thiago Cavalheiro Montebugnoliadora aprender novas tecnologias. Formado pela Faculdade de Tecnologia de Botucatu

SP (FATEC), j desenvolveu softwares utilizando a plataforma .NET, Delphi junto com Banco de Dados SQL Server e Firebird. Atualmente trabalha no Centro de Processamento de Dados da Prefeitura Municipal de Ita-SP colunista mensal da Revista The Club Megazine e consultor Tcnico do The Club. Possui as seguintes certificaes: MCP - Microsoft Certified Professional, MCTS - Microsoft Certified Technology Specialist, MCAD - Microsoft Certified Application Developer e MCSD - Microsoft Certified Solution Developer.

Sobre o autor

fevereiro201430

desafio the club1. Qrsysdata - 2. Registry - 3. Onselect - 4. Override - 5. Vkreturn - 6. Keyprewiew - 7. Sqlexpr - 8. Dbchart - 9. Overload - 10. TheClub - 11. Concat - 12. Locate - 13. Datecompare - 14. Incday

Verticais

1- Objeto da aba Qreport que insere data/hota ou nmero de pgina no relatrio.2- Unit necessria para utilizar os registros do Windows.3- Evento disparado quando um item da combo selecionado.5- Constante que indica a tecla enter no envento OnKeyDown.6- Propriedade do form que habilita o reconhecimento de teclas.8- Objeto que insere grficos ligados ao banco de dados.9- Clausula para sobrecarregar mtodos.11- Funo para concatenar duas strings.

Horizontais

4- Clusula de sobreposio de mtodos.7- Unit do sqldatase.10- Maior clube de programadores do Brasil. (palavra chave)12- Mtodo que localiza registros no adotable.13- Funo para comparar datas.14- Funo para incrementar uma data.

fevereiro2014 05

fevereiro2014