Está en la página 1de 192

Java Avanado com acesso JDBC a Banco de Dados, Arquivos, Swing e Eventos

Java Avanado

Sumrio
1. Frameworks para interfaces grficas..................................1 Objetivos..............................................................................................2 Abstract Window Toolkit (AWT) ...........................................................3 Swing...................................................................................................4 Exerccios.............................................................................................7 Gerenciadores de Layout....................................................1 Objetivos..............................................................................................2 Introduo............................................................................................3 FlowLayout...........................................................................................4 BorderLayout........................................................................................6 GridLayout............................................................................................9 Exerccios...........................................................................................11 Tratamento de Eventos....................................................13 Objetivos............................................................................................14 Listeners.............................................................................................15 Formas de Tratamento de Eventos....................................................16 Eventos de Mouse..............................................................................23 Exerccios...........................................................................................36 Componentes para Interface Grfica...................................1 Objetivos..............................................................................................2 JFrame..................................................................................................3 JLabel...................................................................................................6 JButton.................................................................................................9 JTextField e JPasswordField................................................................12 JTextArea............................................................................................16 JPanel.................................................................................................19 JComboBox.........................................................................................21 Construindo Menus............................................................................24 Entendendo as Caixas de Dilogo......................................................36 JOptionPane........................................................................................37 JTable.................................................................................................41 JScrollPane.........................................................................................44 JFileChooser........................................................................................46 Exerccios...........................................................................................48 Look And Feel....................................................................1 Objetivos.............................................................................................2 Aparncia e Comportamento...............................................................3 Exerccios.............................................................................................6 Arquivos............................................................................1 I

2.

3.

4.

5.

6.

Frameworks para interfaces grficas Objetivos..............................................................................................2 Introduo............................................................................................3 Hierarquia de Dados............................................................................4 Arquivos e Fluxos.................................................................................7 Testando Arquivos.............................................................................13 Criando um Arquivo...........................................................................16 Lendo Dados de um Arquivo..............................................................25 Gerenciamento de memria: Garbage Collector ...............................34 Exerccios...........................................................................................35 7. Acesso a Banco de Dados...................................................1 Objetivos..............................................................................................1 Introduo............................................................................................2 JDBC Drivers.........................................................................................3 Aplicao vs JDBC Driver......................................................................7 JDBC URLs............................................................................................8 Server Side Driver..............................................................................11 Acessando Bases de Dados por JDBC.................................................12 Etapa 1: Connect................................................................................13 Etapa 2: Query...................................................................................16 Etapa 3: Process results.....................................................................20 Etapa 4: Close....................................................................................23 MetaData............................................................................................26 Tipo de Dados....................................................................................27 Resumo Tecnologia JDBC ..................................................................28 Acessando Bases de Dados com JDBC...............................................29 Registrando Fonte de Dados de ODBC...............................................35 Manipulando Banco de Dados com ODBC..........................................37 Processamento de Transaes...........................................................48 Exerccios...........................................................................................49

II

1.Frameworks para interfaces grficas

Frameworks para interfaces grficas

Objetivos
Conhecer os diferentes construo de interfaces grficas frameworks existentes para

Enteder as relaes e a evoluo destes frameworks Conhecer as diferenas entre estes frameworks

Frameworks para interfaces grficas

Abstract Window Toolkit (AWT)

O framework AWT (Abstract Window Toolkit pacote java.awt) foi a primeira interface grfica moderna e difundida para a linguagem Java. Tendo como caractersticas possuir componentes de peso pesado, ou seja, componente que esto associados diretamente a capacidade da plataforma local apresenta como problema principal as diferenas de interao com o usurio sensitivas a plataforma. Este framework serviu de base para a construo do Swing que utiliza alguns de seus recursos. Atualmente este pacote utilizado para completar partes que no foram re-escritas em Swing. Em todo programa Swing sempre haver alguma classe AWT sendo utilizada pois existem eventos e componentes que no foram reimplementados no Swing pelo AWT j atender as necessidades.

Frameworks para interfaces grficas

Swing
As classes que so utilizadas para criar os componentes so parte dos componentes GUI do Swing do pacote javax.swing. Esses so os mais novos componentes GUI da plataforma do Java 2. DICA: Uma forma fcil de diferenciar classes Swing de classes AWT pelo seu prefixo, todas classes Swing inicial com a letra J. Os componentes Swing (como so comumente denominados) so escritos, manipulados e exibidos completamente em Java (chamados componentes Java puros). Os componentes GUI originais do pacote java.awt (Abstract Windowing Toolkit - tambm chamado de AWT) esto diretamente associados com as capacidades de GUI da plataforma local. Ento, um programa Java executando em diferentes plataformas Java tem uma aparncia diferente e, s vezes, at diferentes interaes de usurio em cada plataforma. Juntos, o aspecto e a maneira como o usurio interage com o programa so conhecidos como aparncia e comportamento ("look and feel") desse programa. Os componentes do Swing permitem ao programador especificar uma aparncia e um comportamento diferente para cada plataforma, ou uma aparncia e um comportamento uniforme entre todas as plataformas, ou at mesmo alterar a aparncia e comportamento enquanto o programa est executando. Os componentes Swing so freqentemente referidos como componentes de peso leve - so completamente escritos em Java de modo a no "serem pesados" pelas complexas capacidades GUI da plataforma em que so utilizados. Os componentes AWT (muitos dos quais so equivalentes dos componentes Swing) que so vinculados plataforma local so correspondentemente chamados de componentes de peso pesado - contam com o sistema de janela da plataforma local para determinar sua funcionalidade e sua aparncia e comportamento. Cada componente de peso pesado tem um "peer" (um equivalente do pacote java.awt.peer) que responsvel pelas interaes entre o componente e a plataforma local para exibir e manipular o componente. Vrios componentes Swing ainda so componentes de peso pesado. Em particular, as subclasses de java.awt.Window que exibem janelas na tela ainda requer em interao direta com o sistema local de janelas. A hierarquia de herana das classes que define atributos comportamentos que so comuns para a maioria dos componentes Swing. e

Frameworks para interfaces grficas

java.lang.Object java.awt.Component java.awt.Container javax.swing.JComponent

Cada classe exibida com o nome de seu pacote e nome de classe completamente qualificado. Grande parte da funcionalidade de cada componente GUI derivada dessas classes. Uma classe que herda da classe Component um componente. Por exemplo, a classe Container herda da classe Component e a classe Component herda de Object. Portanto, um Container um Component e um Object, e um Component um Object. Uma classe que herda da classe Container um Container. Portanto, um JComponent um Container. A classe Component define os mtodos que podem ser aplicados a um objeto de qualquer subclasse de Component. Dois dos mtodos que se originam na classe Component so paint e repaint. importante entender os mtodos de classe Component, porque grande parte da funcionalidade herdada por cada subclasse de Component definida originalmente pela classe Component. As operaes comuns para a maioria dos componentes GUI (tanto Swing como AWT) esto localizadas na classe Component. Um Container uma coleo de componentes relacionados. Em aplicativos com JFrames e em Applets, anexamos os componentes ao painel de contedo - um Container. A classe Container define o conjunto de mtodos que podem ser aplicados a um objeto de qualquer subclasse de Container. Um mtodo que se origina na classe Container add. Outro mtodo que origina na classe Container setLayout, que utilizado para especificar o gerenciador de layout que ajudam um Container a posicionar e dimensionar seus componentes. A classe JComponent a superclasse para a maioria dos componentes Swing. Essa classe define o conjunto de mtodos que pode ser aplicado a um objeto de qualquer subclasse de JComponent. Os componentes Swing que derivam da subclasse JComponent tm muitos recursos, incluindo:

Frameworks para interfaces grficas

Uma aparncia e um comportamento plugvel, que podem ser utilizados para personalizar a aparncia e o comportamento quando o programa executa em plataformas diferentes. Teclas de atalho (chamadas de mnemnicas) para acesso direto a componentes GUI pelo teclado. Capacidades comuns de tratamento de eventos para casos onde vrios componentes GUI iniciam as mesmas aes em um programa. Breves descries do propsito de um componente GUI (chamadas de dicas de ferramenta). Elas so exibidas quando o cursor de mouse posicionado sobre o componente por um breve instante. Suporte a tecnologias de auxilio ao deficiente fsico como leitores de tela de braile para pessoas cegas. Suporte para localizao de interface com o usurio - personalizando a interface com o usurio para exibir em diferentes idiomas e convenes culturais.

Frameworks para interfaces grficas

Exerccios
1. Explique a relao existente entre Swing e AWT. 2. Qual a diferena entre componentes de peso pesado e componentes de peso leve? 3. Como identificar facilmente pelo nome de uma classe de interface grfica se esta faz parte do Swing ou AWT?

Frameworks para interfaces grficas

Espao para anotaes

2. Gerenciadores de Layout

Tratamento de Eventos

Objetivos
Apresentar os principais gerenciadores de layout de interface grfica BorderLayout FlowLayout GridLayout Discutir as principais implementaes de layout Identifir a melhor implementao de acordo com o foco de utilizao

Tratamento de Eventos

Introduo
Os gerenciadores de layout so fornecidos para organizar componentes GUI em um conteiner para propsitos de apresentao. Eles fornecem capacidades bsicas de layout que so mais fceis de utilizar do que determinar a posio e o tamanho exatos de cada componente GUI. Isso permite ao programador concentrar-se na aparncia e comportamento bsicos e deixar os gerenciadores de layout processar a maioria dos detalhes de layout. Alguns designers de GUI tambm permitem ao programador utilizar os gerenciadores de layout descritos abaixo:
Gerenciador de Layout

Descrio

FlowLayout

Padro para java.awt.Applet, java.awt.Panel e javax.swing.JPanel. Coloca os componentes seqencialmente (da esquerda para a direita) na ordem que foram adicionados. Tambm possvel especificar a ordem dos componentes utilizando o mtodo add de Container que aceita um Component e uma posio de ndice inteiro como argumentos. Padro para os painis de contedo de JFrames (e outras janelas) e JApplets. Organiza os componentes em cinco reas: Norte, Sul, Leste, Oeste e Centro. Organiza os componentes nas linhas e colunas.

BorderLayout

GridLayout

Tabela 2-1: Descrio dos gerenciadores de layout

A maioria dos exemplos anteriores de applet e de aplicativos em que criamos nossa prpria GUI utilizou o gerenciador de layout FlowLayout. A classe FlowLayout herda da classe Object e implementa a interface Layout.Manager, que define os mtodos que um gerenciador de layout utiliza para organizar e dimensionar componentes GUI em um conteiner.

Tratamento de Eventos

FlowLayout

FlowLayout o gerenciador de layout mais bsico. Os componentes GUI so colocados em um conteiner da esquerda para a direita na ordem em que so adicionados ao mesmo. Quando a borda do conteiner alcanada, os componentes continuam na prxima linha. A classe FlowLayout permite aos componentes GUI ser alinhados esquerda, centralizados (o padro) e alinhados direita.
package com.targettrust.java.capitulo02; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class FlowLayoutDemo extends JFrame { private JButton left, center, right; private Container c; private FlowLayout layout; public FlowLayoutDemo() { super( "FlowLayout Demo" ); layout = new FlowLayout(); c = getContentPane(); c.setLayout( layout ); left = new JButton( "Left" ); left.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { layout.setAlignment( FlowLayout.LEFT ); layout.layoutContainer( c ); } }); c.add( left ); center = new JButton( "Center" ); center.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { layout.setAlignment( FlowLayout.CENTER ); layout.layoutContainer( c ); } }); c.add( center ); right = new JButton( "Right" ); right.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { layout.setAlignment( FlowLayout.RIGHT ); 4

Tratamento de Eventos layout.layoutContainer( c ); }); c.add( right ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setSize( 300, 75 ); setVisible(true); }

public static void main( String args[] ) { FlowLayoutDemo app = new FlowLayoutDemo(); } } Cdigo 2-1: Exemplo de utilizao de FlowLayout.

O aplicativo de exemplo cria trs objetos JButton e os adiciona ao aplicativo que utiliza um gerenciador de layout FlowLayout. Os componentes so automaticamente alinhados no centro. Quando o usurio clica em Left, o alinhamento para o gerenciador de layout alterado para um FlowLayout alinhado esquerda. Quando o usurio clica em Right, o alinhamento para o gerenciador de layout alterado para um FlowLayout alinhado direita. Quando o usurio clica em Center, o alinhamento para o gerenciador de layout alterado para um como visto anteriormente, um layout do container estabelecido com o mtodo setLayout de classe Container. Configuramos o gerenciador de layout do painel de contedo como o FlowLayout. Normalmente, o layout configurado antes de quaisquer componentes GUI serem adicionados a um conteiner.

Figura 2-1:Exemplo de interface construda com FlowLayout

Cada tratador de evento actionPerformed do boto executa duas instrues. Por exemplo, o mtodo actionPerformed para o boto left utiliza o mtodo FlowLayout setAlignment para alterar o alinhamento para o FlowLayout para um FlowLayout alinhado esquerda (FlowLayout .LEFT). O mtodo de interface LayoutManager layoutContainer para especificar que o painel de contedo deve ser reorganizado com base no layout ajustado. De acordo com qual boto foi clicado, o mtodo actionPerformed para cada boto configura o alinhamento do FlowLayout como FlowLayout.LEFT, FlowLayout.CENTER ou FlowLayout.RIGHT.
5

Tratamento de Eventos

BorderLayout

O gerenciador de layout BorderLayout (o gerenciador de layout-padro para o painel de contedo) organiza componentes em cinco regies: Norte, Sul, Leste, Oeste e Centro (Norte corresponde parte superior do container). A classe BorderLayout herda de Object e implementa a interface LayoutManager2 (uma subinterface de LayoutManager que adiciona vrios mtodos para um processamento de layout aprimorado). At cinco componentes podem ser adicionados diretamente a um BorderLayout um para cada regio. Os componentes colocados nas regies Norte e Sul estendem-se horizontalmente para os lados do conteiner e tem a mesma altura que o componente mais alto colocado nessas regies. As regies Leste e Oeste expandem-se verticalmente entre as regies Norte e Sul e tem a mesma largura que o componente mais largo colocado nessas regies. O componente colocado na regio Centro expande-se para tomar todo o espao restante no layout. Se todas as cinco regies so ocupadas, o espao do container inteiro coberto por componentes GUI. Se a regio Norte ou a regio Sul no for ocupada, os componentes GUI nas regies Leste, Centro e Oeste expandem-se verticalmente para preencher o espao restante. Se a regio Leste ou Oeste no for ocupada, o componente GUI na regio Centro expande-se horizontalmente para preencher o espao restante. Se a regio Centro no for ocupada, a rea deixada vazia os outros componentes GUI no se expandem para preencher o espao restante. O aplicativo BorderLayoutDemo demonstra o gerenciador de layout BorderLayout utilizando cinco JButtons.
package com.targettrust.java.capitulo02; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class BorderLayoutDemo extends JFrame implements ActionListener { private JButton b[]; private String names[] = {"Hide North", "Hide South", "Hide East", "Hide West", "Hide Center"}; private BorderLayout layout; public BorderLayoutDemo() { super( "BorderLayout Demo" ); layout = new BorderLayout( 5, 5 ); 6

Tratamento de Eventos

Container c = getContentPane(); c.setLayout( layout ); b = new JButton[ names.length ]; for ( int i = 0; i < names.length; i++ ) { b[ i ] = new JButton( names[ i ] ); b[ i ].addActionListener( this ); } c.add( c.add( c.add( c.add( c.add( b[ b[ b[ b[ b[ 0 1 2 3 4 ], ], ], ], ], BorderLayout.NORTH ); BorderLayout.SOUTH ); BorderLayout.EAST ); BorderLayout.WEST ); BorderLayout.CENTER );

setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setSize( 300, 200 ); setVisible(true);

public void actionPerformed( ActionEvent e ) { for ( int i = 0; i < b.length; i++ ) { if ( e.getSource() == b[ i ] ) { b[ i ].setVisible( false ); } else { b[ i ].setVisible( true ); } } layout.layoutContainer( getContentPane() ); } public static void main( String args[] ) { BorderLayoutDemo app = new BorderLayoutDemo(); } } Cdigo 2-2: Exemplo de utilizao de BorderLayout.

No construtor de BorderLayout os argumentos especificam o nmero de pixels entre componentes que so organizados horizontalmente (espaamento horizontal) e o nmero de pixels entre componentes que so organizados verticalmente (espaamento vertical), respectivamente. O construtor-padro BorderLayout fornece 0 pixel de espaamento horizontal e verticalmente. Utilizamos o mtodo setLayout para configurar o layout do painel de contedo como layout. Adicionar componentes a um BorderLayout requer um mtodo add diferente da classe Container, que aceita dois argumentos o Component para adicionar e a regio em que o Component ser colocado. Por exemplo, especificamos que o b[0] deve ser colocado na posio NORTE.

Tratamento de Eventos

Figura 2-2: Exemplo de interface com BorderLayout

Os componentes podem ser adicionados em qualquer ordem, mas apenas um componente pode ser adicionado a cada regio. Quando o usurio clica em um JButton particular no layout, o mtodo actionPerformed chamado. O comando for utiliza a seguinte estrutura condicional: Para ocultar o JButton particular que gerou o evento. O mtodo setVisible (herdado em JButton da classe Component) chamado com um argumento false. Se o JButton atual no array no o que gerou o evento, o mtodo setVisible chamado com um argumento true para assegurar que o JButton exibido na tela. Utilizamos o mtodo LayoutManager layoutContainer para recalcular o layout do painel de contedo. Tente redimensionar a janela de aplicativo para ver como as vrias regies redimensionam-se baseadas na largura e altura da janela.

Tratamento de Eventos

GridLayout
O gerenciador de layout GridLayout divide o container em uma grade de modo que os componentes podem ser colocados nas linhas e colunas. A classe GridLayout herda diretamente da classe Object e implementa a interface LayoutManager. Cada Component em um GridLayout tem a mesma largura e altura. Os componentes so adicionados a um GridLayout iniciando a clula na parte superior esquerda da grade e prosseguindo da esquerda para a direita at a linha estar cheia. Ento o processo continua da esquerda para a direita na prxima linha da grade, e assim por diante. Este exemplo demonstra o gerenciador de layout GridLayout utilizando seis JButtons.

package com.targettrust.java.capitulo02; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class GridLayoutDemo extends JFrame implements ActionListener { private private private private private JButton b[]; String names[] = { "one", "two", "three", "four", "five", "six" }; boolean toggle = true; Container c; GridLayout grid1, grid2;

public GridLayoutDemo() { super( "GridLayout Demo" ); grid1 = new GridLayout( 2, 3, 5, 5 ); grid2 = new GridLayout( 3, 2 ); c = getContentPane(); c.setLayout( grid1 ); b = new JButton[ names.length ]; for (int i = 0; i < names.length; i++ ) { b[ i ] = new JButton( names[ i ] ); b[ i ].addActionListener( this ); c.add( b[ i ] ); } setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setSize( 300, 150 ); setVisible(true); } public void actionPerformed( ActionEvent e ) { if ( toggle ) { c.setLayout( grid2 ); } else { c.setLayout( grid1 ); } 9

Tratamento de Eventos toggle = !toggle; c.validate();

public static void main( String args[] ) { GridLayoutDemo app = new GridLayoutDemo(); } } Cdigo 2-3: Exemplo de utilizao de GridLayout.

Defininos dois objetos GridLayout. O construtor GridLayout utilizado especifica um GridLayout com 2 linhas, 3 colunas, 5 pixels de espaamento horizontal entre os Components na grade e 5 pixels de espaamento vertical entre Components na grade. O prximo construtor GridLayout especifica um GridLayout com 3 linhas, 2 colunas e nenhum espaamento.

Figura 2-3: Exemplo de interface GridLayout

Os objetos JButton nesse exemplo so inicialmente organizados utilizando grid1 (associado ao painel de contedo com o mtodo setLayout). O primeiro componente adicionado primeira coluna da primeira linha. O prximo componente adicionado segunda coluna da primeira linha etc. Quando um JButton pressionado, o mtodo actionPerformed chamado. Cada chamada para actionPerformed alterna o layout entre grid2 e grid1. Redesenhos um container cujo layout foi alterado onde o mtodo Container validate recalcula o layout do container com base no gerenciador de layout atual para o Container e o conjunto atual de componentes GUI exibidos.

10

Tratamento de Eventos

Exerccios
1. Quais as diferenas entre FlowLayout, BorderLayout e GridLayout? 2. Crie um tabuleiro de Xadrez utilizando os gerenciadores de Layout que voc estudou neste captulo. Para isto veja a imagem abaixo:

11

Tratamento de Eventos

Espao para anotaes

12

Tratamento de Eventos

3. Tratamento de Eventos

13

Tratamento de Eventos

Objetivos
java eventos Entender como podem ser tratados os eventos na linguagem Conhecer as principais interfaces para tratar eventos Criar uma aplicao e utilizar o mecanismo de tratamento de

14

Tratamento de Eventos

Listeners
Quando ocorre uma interao com o usurio, um evento automaticamente enviado para o programa. Informaes de eventos GUI so armazenadas em um objeto de uma classe que estende AWTEvent. Os tipos de evento de pacote java.awt.Event so ainda utilizados com os componentes Swing. Tambm foram adicionados outros tipos de evento que so especficos para vrios tipos de componentes Swing. Novos tipos de evento de componente do Swing so definidos no pacote javax.swing.Event. Para processar um evento de interface grfica com o usurio, o programador deve realizar duas tarefas principais - registrar um ouvinte de eventos (Listener) e implementar um tratador (handler) de eventos. Um ouvinte de eventos para um evento GUI um objeto de uma classe que implementa uma ou mais das interfaces ouvintes de eventos dos pacotes java.awt.Event e javax.swing.Event. Muitos dos tipos de ouvinte de eventos so comuns aos componentes Swing e AWT. Esses tipos so definidos no pacote java.awt.Event. Tipos adicionais de ouvinte de eventos que so especficos de componentes Swing so definidos no pacote javax.swing.Event. Um objeto ouvinte de eventos "ouve" tipos especficos de eventos gerados no mesmo objeto ou por outros objetos (normalmente componentes GUI) em um programa. Um tratador de eventos um mtodo que automaticamente chamado em resposta a um tipo de evento em particular. Cada interface ouvinte de eventos especifica um ou mais mtodos de tratamento de evento que devem ser definidos na classe que implementa a interface ouvinte de eventos. Lembre-se de que as interfaces definem mtodos abstract. Qualquer classe que implementa uma interface deve definir todos os mtodos dessa interface; caso contrrio, a classe uma classe abstract e no pode ser utilizada para criar objetos. O uso de ouvintes de eventos em tratamento de eventos conhecido como modelo de delegao de evento - o processamento de um evento delegado a um objeto particular no programa. Quando um evento ocorre, o componente GUI com o qual o usurio interagiu notifica seus ouvintes registrados chamando o mtodo de tratamento de evento apropriado de cada ouvinte. Por exemplo, quando o usurio pressiona a tecla Enter em um JTextField, o mtodo actionPerformed do ouvinte registrado chamado.

15

Tratamento de Eventos

Formas de Tratamento de Eventos

J conhecendo o funcionamento dos Listeners (conforme item anterior) deve-se compreender de que forma capturar estes eventos atravs dos ouvintes (Listeners). Existem vrias interfaces de tratamento de eventos, o objetivo deste captulo explicar as formas de como trabalhar com estas interfaces e no as interfaces propriamente ditas. Desta forma, este captulo baseado em uma nica interface a ActionListener, a fim de facilitar o estudo. Todas interfaces (ActionListener, MouseListener, WindowListener, KeyListener, MouseMotionListener) sero detalhadas no prximo captulo O tratamento de eventos pode ser feito atravs de trs formas, conforme seguem as subsees deste captulo.

16

Tratamento de Eventos

Implementando uma interface

Esta forma de realizar o tratamento de eventos consiste em uma classe implementar uma interface para que a mesma possa ter comportamentos que a habilitem tratar determinados tipos de eventos. Isto pode ser feito pela prpria classe onde os ventos so originados ou por outra classe. Os objetos criados a partir desta classe tero a capacidade de responder a eventos. Existem vrias interfaces que descrevem tipos de comportamentos, tais como: ActionListener, MouseListener, WindowListener, KeyListener, MouseMotionListener. Estas interfaces possuem mtodos abstratos que obrigatoriamente devem ser implementados quando utilizadas, estes mtodos so os responsveis pelo tratamento dos eventos. Veja abaixo um exemplo de implementao de interface pela prpria classe onde os eventos so originados:
package com.targettrust.java.capitulo03; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ExemploEventos extends JFrame implements ActionListener { public ExemploEventos() { super( "Exemplo de tratamento de eventos" ); JButton botao = new JButton("Teste"); botao.setSize(80, 20); getContentPane().setLayout(new FlowLayout()); getContentPane().add(botao); botao.addActionListener(this); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize( 350, 200 ); setVisible( true ); } public void actionPerformed(ActionEvent e) { JOptionPane.showMessageDialog(getContentPane(), e.getActionCommand()); } public static void main(String[] args) { ExemploEventos app = new ExemploEventos(); }

} Cdigo 3-1: Cdigo fonte de exemplo de tratamento de eventos. 17

Tratamento de Eventos

O programa acima exemplifica o tratamento de eventos atravs da utilizao de uma interface AcionListener. Ao implementer a interface action listener necessrio utilizar o mtodo actionPerformed() o qual recebe como parmetro o evento. Alm de implementer a interface ActionListener e programas o mtodo actionPerformed o programa realize uma achamada ao mtodo addActionListener do objeto botao (JButton), este feito para registrar ao ouvinte quais objetos devem ser tratados. Resumindo, implementer interfaces para tartar eventos se divide em 3 passos bsicos: 1. Implementar a interface 2. Implementar seus mtodos abstratos 3. Definir quais objetos sero escutados, adicionando-os ao listener.

18

Tratamento de Eventos

Delegando o tratamento a outro objeto

A segunda forma de realizar o tratamento de eventos delegando a um outro objeto o tratamento dos eventos, ou seja, o programa possui uma classe com a GUI e uma outra classe apenas para tartar os eventos desta.
package com.targettrust.java.capitulo03; import java.awt.*; import javax.swing.*; public class DelegandoEventos extends JFrame { public DelegandoEventos() { setTitle("Exemplo de Tratamento de Eventos"); setSize(400, 200); setDefaultCloseOperation(EXIT_ON_CLOSE); JButton botao = new JButton("Sair"); botao.setSize(80, 20); getContentPane().setLayout(new FlowLayout()); getContentPane().add(botao); botao.addActionListener(new TratandoEventos()); setVisible(true); } public static void main(String[] args) { DelegandoEventos app = new DelegandoEventos(); } Cdigo 3-2: Delegando a outro objeto o tratamento de eventos, contruo da GUI.

O programa acima cria a GUI com uma janela e um boto sair. Observando o cdigo nota-se a chamada ao mtodo botao.addActionListener(new TratandoEventos()). Este mtodo esta delegando a outra classe (TratandoEventos) o tratamento dos eventos sobre o boto sair.

Abaixo segue o cdigo da classe TratandoEventos:


19

Tratamento de Eventos

package com.targettrust.java.capitulo03; import java.awt.event.*; import javax.swing.*; public class TratandoEventos implements ActionListener { public void actionPerformed(ActionEvent e) { System.exit(0); } } Cdigo 3-3: Tratando evento do boto sair.

Neste programa foi implementada a interface ActionListener e implementado o mtodo actionPerformed que esta recebendo como parmetro os eventos do boto sair do primeiro programa pois foi adicionado ao ouvinte. Ao receber qualquer aa sobre este boto o programa realize um System.exit(0);

20

Tratamento de Eventos

Utilizando Classes Annimas Internas


A terceira e ltima forma de realizar tratamento de eventos atravs de classes annimas internas (Anonymys Inner Class). Este modo de tratamento semelhante a delegar a outro objeto (veja o tpico anterior) com a diferena de no possuir uma classe nomeada para tratar o evento, ou seja, o objeto criado com uma instruo new no proprio mtodo addActionListener. Resumindo, esta uma forma mais prtica de implementer o tratamento de eventos, pois no existe a necessidade de duas classes nomeadas e possivelmente em arquivos separados.
package com.targettrust.java.capitulo03; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ClassesAnonimas extends JFrame { public ClassesAnonimas() { super("Exemplo de Tratamento de Eventos"); JButton botao = new JButton("Sair"); botao.setSize(80, 20); getContentPane().setLayout(new FlowLayout()); getContentPane().add(botao); botao.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { System.exit(0); } } ); setSize(400, 200); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); {

public static void main(String[] args) new ClassesAnonimas(); }

} Cdigo 3-4: Tratando eventos com classes annimas internas.

Prestando ateno no mtodo addActionListener() do objeto boto (JButton) verifica-se que no existe a chamada a uma classe criada anteriormente e sim a um objeto criadao dentro do mtodo atravs da instruo new. O trecho de cdigo new ActionListener() { }, possui a mesma funcionalidade que foi detalhada na subseo anterior deste mesmo captulo com a diferena de no nomear uma nova classe e sim fazer a declarao desta no prprio mtodo de ligao com o ouvinte.
21

Tratamento de Eventos

Interfaces para Tratamento de Eventos


O objetivo desta subseo explicar o funcionamento de cada uma das interfaces existentes para tratamento de eventos.
Categoria
Aco Item Movimento do mouse Boto do mouse

Nome da interface
ActionListener ItemListener

Adaptador
-

Mtodos
public void actionPerformed(ActionEvent e) public void itemStateChanged(ItemEvent e) public void mouseDragged(MouseEvent e) public void mouseMoved(MouseEvent e) public void mousePressed(MouseEvent e) public void mouseReleased(MouseEvent e) public void mouseEntered(MouseEvent e) public void mouseExited(MouseEvent e) public void mouseClicked(MouseEvent e) public void keyPressed(KeyEvent e) public void keyReleased(KeyEvent e) public void keyTyped(KeyEvent e) public void focusGained(FocusEvent e) public void focusLost(FocusEvent e) public void adjustmentValueChanged(AdjustmentEvent e) public void componentMoved(ComponentEvent e) public void componentHidden(ComponentEvent e) public void componentResized(ComponentEvent e) public void componentShown(ComponentEvent e)

MouseMotionListener MouseMoutionAdapter MouseListener MouseAdapter

Tecla Foco Ajuste Componente

KeyListener FocusListener AjustmentListener ComponentListener

KeyAdapter FocusAdapter

ComponentAdapter

Janela

WindowListener

WindowAdapter

public void windowClosing(WindowEvent e) public void windowOpened(WindowEvent e) public void windowIconified(WindowEvent e) public void windowDeiconified(WindowEvent e) public void windowClosed(WindowEvent e) public void windowActivated(WindowEvent e) public void windowDeactivated(WindowEvent e)

Recipiente

ContainerListener

ContainerAdapter

public void componentRemoved(ContainerEvent e) public void componentAdded(ContainerEvent e) public void textValueChanged(TextEvent e) public void mouseWheelMoved(MouseWheelEvent e) public void windowStateChanged(WindowEvent e)

Texto Mouse Wheel Estado da Janela

TextListener MouseWheelListener WindowStateListener

22

Tratamento de Eventos

Eventos de Mouse
Esta seo apresenta as interfaces ouvintes de eventos MouseListener e MouseMotionListener para tratar eventos de mouse. Os eventos de mouse podem ser capturados por qualquer componente GUI que deriva de java.awt.Component. Os mtodos de interfaces MouseListener e MouseMotionListener so resumidos em:

public void mousePressed( MouseEvent e ) { }

Chamado quando um boto do mouse pressionado com o cursor de mouse em um componente.

public void mouseClicked( MouseEvent e ) { }

Chamado quando um boto do mouse pressionado e liberado em um componente sem mover o cursor do mouse.

public void mouseReleased( MouseEvent e ) { }

Chamado quando um boto do mouse liberado depois de ser pressionado. Esse evento sempre precedido por uni evento mousePressed.

public void mouseEntered( MouseEvent e ) { }

Chamado quando o cursor do mouse entra nos limite de um componente.

public void mouseExited( MouseEvent e ) { }

Chamado quando o cursor do mouse deixa os limite de um componente.

public void mouseDragged( MouseEvent e ) { }

Chamado quando o boto do mouse pressionado e o mouse movido. Esse evento sempre precedido por uma chamada para mousePressed.

public void mouseMoved( MouseEvent e )

{}

Chamado quando o mouse movido com o cursor do mouse em um componente.

Cada um dos mtodos de tratamento de eventos do mouse aceita um objeto MouseEvent como seus argumentos. Um objeto MouseEvent contm as informaes sobre o evento de mouse que ocorreu, incluindo as coordenadas x e y da localizao onde o evento ocorreu.

23

Tratamento de Eventos

Os mtodos MouseListener e MouseMotionListener so chamados automaticamente quando o mouse interage com um Component se os objetos ouvintes esto registrados em um Component particular. O mtodo mousePressed chamado quando um boto do mouse pressionado com o cursor do mouse sobre um componente. Utilizando mtodos e constantes da classe InputEvent (a superclasse de MouseEvent), um programa pode determinar em que boto do mouse o usurio clicou. O mtodo mouseClicked chamado sempre que um boto do mouse liberado sem mover o mouse depois de uma operao mousePressed. O mtodo mouseReleased chamado sempre que um boto do mouse liberado. O mtodo mouseEntered chamado quando o cursor do mouse entra nos limites fisicos de um Component. O mtodo mouseExited chamado quando o cursor de mouse deixa os limites fisicos de um Component. O mtodo mouseDragged chamado quando o boto do mouse pressionado e mantido pressionado e o mouse movido (um processo conhecido como arrastar). O evento mouseDragged precedido por um evento mousePressed e seguido por um evento mouseReleased. O mtodo mouseMoved chamado quando o mouse movido com o cursor de mouse sobre um componente (e nenhum boto do mouse pressionado). O aplicativo MouseTracker demonstra os mtodos MouseListener e MouseMotionListener. A classe do aplicativo implementa as duas interfaces de modo a poder ouvir seus prprios eventos de mouse. Observe que todos os sete mtodos dessas duas interfaces devem ser definidos pelo programador quando uma classe implementa as duas interfaces.
package com.targettrust.java.capitulo03; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MouseTracker extends JFrame implements MouseListener, MouseMotionListener { private JLabel statusBar; public MouseTracker() { super( "Demonstrando Evento do mouse" ); statusBar = new JLabel(); 24

Tratamento de Eventos getContentPane().add( statusBar, BorderLayout.SOUTH ); addMouseListener( this ); addMouseMotionListener( this ); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE ); setSize( 275, 100 ); show();

public void mouseClicked( MouseEvent e ) { statusBar.setText( "Clicked em [" + e.getX() + ", " + e.getY() + "]" ); } public void mousePressed( MouseEvent e ) { statusBar.setText( "Pressed em [" + e.getX() + ", " + e.getY() + "]" ); } public void mouseReleased( MouseEvent e ) { statusBar.setText( "Released em [" + e.getX() + ", " + e.getY() + "]" ); } public void mouseEntered( MouseEvent e ) { statusBar.setText( "Mouse na janela" ); } public void mouseExited( MouseEvent e ) { statusBar.setText( "Mouse fora da janela " ); } public void mouseDragged( MouseEvent e ) { statusBar.setText( "Dragged em [" + e.getX() + ", " + e.getY() + "]" ); } public void mouseMoved( MouseEvent e ) { statusBar.setText( "Moved em [" + e.getX() + ", " + e.getY() + "]" ); } public static void main( String args[] ) { MouseTracker app = new MouseTracker(); } } Cdigo 3-5: Tratando eventos do mouse

Cada evento de mouse resulta na exibio de um String em JLabel statusBar na parte inferior da janela. Definimos JLabel statusBar e o anexamos ao painel de contedo. At agora, toda as vezes que utilizamos o painel de contedo, o mtodo setLayout foi chamado para configurar o gerenciador de layout do painel de contedo como um FlowLayout. Isso permitiu ao painel de contedo exibir os componentes GUI que anexamos a ele da esquerda para a direta. Se os componentes GUI no se ajustarem em uma linha, o FlowLayout cria linhas adicionais para continuar exibindo os componentes GUI. Realmente, o gerenciador padro de layout um BorderLayout que divide a rea do painel de contedo em cinco regies - norte, sul, leste, oeste e centro.
25

Tratamento de Eventos

Figura 3-1: Exemplo de tratamento de eventos do mouse

Utilizamos uma nova verso do mtodo Container add para anexar statusBar regio BorderLayout.SOUTH, que se estende ao longo de toda a parte inferior do painel de contedo. Registramos o objeto de janela MouseTracker como o ouvinte para seus prprios eventos de mouse. Os mtodos add.MouseListener e addMouseMotionListener so os mtodos Component que podem ser utilizados para registrar ouvintes de eventos de mouse para um objeto de qualquer classe que estenda Component. Quando o mouse entra ou sai da rea do aplicativo, o mtodo mouseEntered e o mtodo mouseExited so chamados, respectivamente. Ambos os mtodos exibem uma mensagem na statusBar indicando que o mouse est dentro do aplicativo ou que o mouse est fora do aplicativo. Quando quaisquer dos outros cinco eventos ocorrem, eles exibem uma mensagem na statusBar que inclui um String representando o evento que ocorreu e as coordenadas onde o evento de mouse ocorreu. As coordenadas x e y do mouse em que o evento ocorreu so obtidas com os mtodos MouseEvent getX e getY, respectivamente.

26

Tratamento de Eventos

Classes Adaptadoras

Muitas das interfaces ouvintes de eventos fornecem mltiplos mtodos: MouseListener e MouseMotionListener so exemplos. No sempre desejvel definir cada mtodo em uma interface ouvinte de evento. Por exemplo, um programa pode precisar apenas do tratador de interface MouseListener mouseClicked ou do tratador MouseMotionListener mouseDragged. Em nossos aplicativos de janela (subclasses de JFrame), o trmino do aplicativo foi tratado com o windowClosing da interface WindowListener, que na realidade especifica sete mtodos de tratamento de eventos de janela. Para muitas das interfaces ouvintes que contm mltiplos mtodos, os pacotes java.awt.Event e javax.swing.Event fornecem classes adaptadoras de ouvinte de eventos. Uma classe adaptadora implementa uma interface e fornece uma implementao padro (com o corpo de um mtodo vazio) de cada mtodo na interface. As classes adaptadoras java.awt.Event so mostradas abaixo junto com as interfaces que elas implementam.
Implementa a Interface ComponentListener ContainerListener FocusListener KeyListener MouseListener MouseMotionListener WindowListener Classe Adaptadora de Eventos ComponentAdapter ContainerAdapter FocusAdapter KeyAdapter MouseAdapter MouseMotionAdapter WindowAdapter

Tabela 3-1: Interfaces implementadas por classes adaptadoras.

O programador pode estender a classe adaptadora para herdar a implementao padro de cada mtodo e ento anular o(s) mtodo(s) necessrio(s) para tratamento de eventos.
27

Tratamento de Eventos

A implementao padro de cada mtodo na classe adaptadora tem um corpo vazio. Isso exatamente o que temos feito em cada exemplo de aplicativo que estende JFrame e define o mtodo windowClosing para tratar o fechamento da janela e o encerramento do aplicativo. O aplicativo Painter utiliza o tratador de evento mouseDragged para criar um programa simples de desenho. O usurio pode desenhar figuras com o mouse arrastando o mouse no fundo da janela. Como no pretendemos utilizar o mtodo mouseMoved, nosso MouseMotionListener definido como uma subclasse de MouseMotionAdapter. Essa classe j define mouseMoved e mouseDragged, ento podemos simplesmente anular mouseDragged para fornecer a funcionalidade de desenho.
package com.targettrust.java.capitulo03; import java.awt.event.*; import java.awt.*; import javax.swing.*; public class Painter extends JFrame { private int xValue = -10, yValue = -10; private Container c; public Painter() { super( "Painter" ); c = getContentPane(); c.add(new Label( "Arraste o mouse para desenhar" ),BorderLayout.SOUTH); addMouseMotionListener( new MouseMotionAdapter() { public void mouseDragged( MouseEvent e ) { xValue = e.getX(); yValue = e.getY(); repaint(); } } ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setSize( 300, 150 ); setVisible(true);

public void paint( Graphics g ) { g.fillOval( xValue, yValue, 4, 4 ); } public static void main( String args[] ) { Painter app = new Painter(); } } Cdigo 3-6: Cdigo exemplo de classes adaptadoras.

28

Tratamento de Eventos

As variveis de instncia xValue e yValue armazenam as coordenadas do evento mouseDragged. Inicialmente, as coordenadas so configuradas fora da rea de janela para evitar que uma oval seja desenhada na rea de fundo na primeira chamada a paint quando a janela exibida. Registramos um MouseMotionListener para ouvir os eventos de movimento de mouse da janela (lembre-se de que uma chamada para um mtodo que no precedida por uma referncia e por um operador de ponto na realidade precedida por this., indicando que o mtodo chamado para a instncia atual da classe em tempo de execuo). Definimos uma classe interna annima que estende MouseMotionAdapter (que implementa MouseMotionListener). a classe

A classe interna annima herda uma implementao padro dos mtodos mouseMoved e mouseDragged. Portanto, a classe interna annima j satisfaz o requisito de que em todos os mtodos de uma interface devem ser implementados. Entretanto, os mtodos padro no fazem nada quando so chamados. Portanto, anulamos o mtodo mouseDragged para capturar as coordenadas x e y do evento de mouse arrastado e as armazenamos nas variveis de instncia xValue e yValue; ento, chamamos repaint para comear a desenhar a prxima oval no fundo (o que realizado pelo mtodo paint). Registramos um WindowListener para ouvir os eventos de janela da janela de aplicativo (tais como fechar a janela). Definimos uma classe interna annima que estende a classe WindowAdapter (que implementa WindowListener).

29

Tratamento de Eventos Figura 3-2: Exemplo de utilizao de classes adaptadoras.

A classe interna annima herda uma implementao padro dos sete diferentes mtodos de tratamento de eventos de janelas. Portanto, a classe interna annima j satisfaz o requisito de que uma interface deve ser implementada em todos os mtodos. Entretanto, os mtodos padro no fazem nada quando so chamados. Ento, anulamos o mtodo windowClosing para terminar o aplicativo quando o usurio clica na caixa de fechamento da janela de aplicativo. Repare que, quando voc arrasta o mouse, todos os ovais permanecem na janela. isso devido a um recurso especial dos componentes GUI Swing chamado de buffer duplo em que todo desenho realmente ocorre em uma imagem armazenada na memria, e ento a imagem inteira exibida na janela (ou outro componente GUI). Isso ajuda a melhorar a qualidade grfica em uma GUI Swing. O aplicativo MouseDetails demonstra como determinar o nmero de cliques de mouse (isto , a contagem de cliques) e como distinguir entre diferentes botes do mouse. O ouvinte de eventos nesse programa um objeto da classe interna MouseClickHandler que estende MouseAdapter para possamos definir apenas o mtodo mouseClicked de que precisamos nesse exemplo.

package com.targettrust.java.capitulo03; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class MouseDetails extends JFrame { private String s = ""; private int xPos, yPos; public MouseDetails() { super( "Mouse clicks and buttons" ); addMouseListener( new MouseClickHandler() ); setSize( 350, 150 ); show(); } public void paint( Graphics g ) { g.drawString( "Clicked @ [" + xPos + ", " + yPos + "]", xPos, yPos ); } public static void main( String args[] ) { MouseDetails app = new MouseDetails(); } 30

Tratamento de Eventos

private class MouseClickHandler extends MouseAdapter { public void mouseClicked( MouseEvent e ) { xPos = e.getX(); yPos = e.getY(); String s = "Clicked " + e.getClickCount() + " vez(s)"; if ( e.isMetaDown() ) s += " com o boto direito do mouse"; else if ( e.isAltDown() ) s += " com o boto do centro"; else s += " com o boto da esquerda"; setTitle( s ); repaint();

} }

} Cdigo 3-7: Exemplo de utilizao de classes adaptadoras.

Um usurio de um programa Java pode estar em um sistema com um, dois ou trs botes do mouse. Java fornece um mecanismo para distinguir entre os botes do mouse.

Figura 3-3: Exemplo de utilizao de classes adaptadoras.

A classe MouseEvent herda vrios mtodos de classe InputEvent que podem distinguir entre botes do mouse em um mouse de mltiplos botes ou podem simular um mouse de mltiplos botes com um pressionamento de tecla combinado e dique do boto do mouse.

Os mtodos InputEvent utilizados para distinguir entre cliques do boto do mouse so:
Mtodo InputEvent isMetaDown () Descrio Esse mtodo retoma true quando o usurio clica com o boto direito de um mouse com dois ou trs botes. Para simular um clique de boto direito com um mouse de um boto, o usurio pode pressionar a tecla Meta no teclado e clicar no boto do mouse.
31

Tratamento de Eventos

Esse mtodo retoma true quando o usurio clica no boto isAltDown ( ) do centro do mouse em um mouse com trs botes. Para simular um clique com o boto do centro do mouse em um mouse com um ou dois botes, o usurio pode pressionar a tecla Alt no teclado e clicar no boto do mouse.
Tabela 3-2: Quadro de mtodos InputEvent

Java pressupe que cada mouse contm um boto esquerdo do mouse. Portanto, simples testar um clique com o boto esquerdo do mouse. Entretanto, usurios com mouse de um ou dois botes devem utilizar uma combinao de pressionamentos de teclas no teclado e clicar no mouse ao mesmo tempo para simular os botes ausentes no mouse. No caso de um mouse com um ou dois botes, esse programa pressupe que o boto do centro do mouse clicado se o usurio mantm pressionada a tecla <Alt> e clica no boto do mouse esquerdo em um mouse de dois botes ou com boto nico do mouse em um mouse de um boto. No caso de um mouse de um boto, esse programa pressupe que o boto direito do mouse clicado se o usurio mantm pressionada a tecla Meta e clica no boto do mouse. O mtodo mouseClicked primeiro captura as coordenadas onde o evento ocorreu e as armazena em variveis de instncia xPos e yPos da classe MouseDetails. Criamos um String contendo o nmero de cliques de mouse (como retomado pelo mtodo MouseEvent getClickCount). A estrutura condicional utiliza os mtodos isMetaDown e isAltDown para determinar qual boto do mouse o usurio clicou e acrescenta um string apropriado para String s em cada caso. O String resultante exibido na barra de ttulo da janela com o mtodo setTitle (herdado na classe JFrame da classe Frame). Chamamos repaint para iniciar uma chamada a paint para desenhar um String na localizao em que o usurio clicou com o mouse.

32

Tratamento de Eventos

Tratando Eventos do Teclado


Esta seo apresenta a interface ouvinte de eventos KeyListener para tratar eventos do teclado. Eventos de tecla so gerados quando as teclas no teclado so pressionadas e liberadas. Uma classe que implementa KeyListener deve fornecer definies para os mtodos keyPressed keyReleased e keyTyped, cada uma das quais recebe um KeyEvent como seu argumento. A classe KeyEvent uma subclasse de InputEvent. O mtodo keyPressed chamado em resposta ao pressionamento de qualquer tecla. O mtodo keyTyped chamado em resposta ao pressionamento de qualquer tecla que no uma tecla de ao (por exemplo, uma tecla de seta, <Home>, <End>, <Page Up>, <Page Down>, uma tecla de funo, <Num Lock>, <Print Screen>, <Scroll Lock>, <Caps Lock> e <Pause>). O mtodo keyReleased chamado quando a tecla liberada depois de qualquer evento keyPressed ou keyTyped. Consulte referncia aos mtodos KeyListener. A classe KeyDemo implementa a interface KeyListener, ento todos os trs mtodos so definidos no aplicativo.
package com.targettrust.java.capitulo03; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class KeyDemo extends JFrame implements KeyListener { private String line1 = "", line2 = ""; private String line3 = ""; private JTextArea textArea; public KeyDemo() { super( "Demostrando eventos de mouse" ); textArea = new JTextArea( 10, 15 ); textArea.setText( "Pressione uma tecla " ); textArea.setEnabled( false ); addKeyListener( this ); getContentPane().add( textArea ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setSize( 350, 100 ); setVisible(true); } public void keyPressed( KeyEvent e ) { line1 = "Key pressed: " + e.getKeyText( e.getKeyCode() ); setLines2and3( e ); 33

Tratamento de Eventos } public void keyReleased( KeyEvent e ) { line1 = "Key released: " + e.getKeyText( e.getKeyCode() ); setLines2and3( e ); } public void keyTyped( KeyEvent e ) { line1 = "Key typed: " + e.getKeyChar(); setLines2and3( e ); } private void setLines2and3( KeyEvent e ) { line2 = "Esta a tecla " + ( e.isActionKey() ? "" : "no " ) + " uma tecla de ao"; String temp = e.getKeyModifiersText( e.getModifiers() ); line3 = "Modificador pressionado: " + ( temp.equals( "" ) ? "nenhum" : temp ); textArea.setText( line1 + "\n" + line2 + "\n" + line3 + "\n" ); } public static void main( String args[] ) { KeyDemo app = new KeyDemo(); }

} Cdigo 3-8: Exemplo de tratamento de eventos de teclado.

O construtor registra o aplicativo para tratar seus prprios eventos de tecla com o mtodo addKeyListener. O mtodo addKeyListener definido na classe Component, ento cada subclasse de Component pode notificar KeyListeners de eventos de tecla para esse Component. Adicionamos a JTextArea textArea (onde a sada do programa exibida) ao painel de contedo. Quando um nico Component adicionado a um BorderLayout, o Component ocupa o inteiro Container por default. Os mtodos keyPressed e keyReleased utilizam o mtodo KeyEvent getKeyCode para obter o cdigo de tecla virtual da chave que foi pressionada. A classe KeyEvent mantm um conjunto de constantes o cdigo de tecla virtual constante que representa cada tecla no teclado.

34

Tratamento de Eventos Figura 3-4: Exemplo de tratamento de eventos do teclado.

Essas constantes podem ser comparadas com o valor de retorno de getKeyCode para testar as teclas individuais no teclado. O valor retornado por getKeyCode passado para o mtodo KeyEvent getKeyText, que retorna um String contendo o nome da tecla que foi pressionada. Para uma lista completa de constantes de tecla virtual, veja a documentao on-line para a classe KeyEvent (pacote java.awtEvent). O mtodo keyTyped utiliza o mtodo KeyEvent getKeyChar para obter o valor Unicode do caractere digitado. Todos os trs mtodos de tratamento de eventos terminam chamando o mtodo setLines2and3 e passando para ele o objeto KeyEvent. Esse mtodo utiliza o mtodo KeyEvent isActionKey para determinar se a tecla no evento era uma tecla de ao. Alm disso, o mtodo InputEvent getModifiers chamado para determinar se quaisquer teclas modificadoras (como <Shift>, <Alt> e <Ctrl>) foram pressionadas quando o evento de tecla ocorreu. O resultado desse mtodo passado para o mtodo KeyEvent getKeyModifiersText, que produz um string contendo os nomes das teclas modificadoras pressionadas. Nota: Se voc precisa testar uma tecla especfica no teclado, a classe KeyEvent fornece uma constante de tecla para cada tecla no teclado. Essas constantes podem ser utilizadas a partir dos tratadores de eventos de tecla para determinar se uma tecla particular foi pressionada. Alm disso, para determinar se as teclas <Alt>, <Ctrl>, <Meta> e <Shift> so pressionadas individualmente, os mtodos InputEvent isAltDown, IsControlDown, isMetaDown e isShiftDown retornam um boolean indicando se a tecla particular foi pressionada durante o evento de tecla.

35

Tratamento de Eventos

Exerccios
1. Para praticar o tratamento de eventos, crie uma interface grfica de uma tela de login de acordo com a figura abaixo:

2. Implemente um listener para realizar o encerramento do processo java criado pelo mtodo main da aplicao quando o usurio clicar no X da janela. 3. Implemente listeners para os botes que possam realizar aes de umclique de mouse. Para o boto sair faa tambm o encerramento do processo. 4. Para o campo de senha implemente um listener que seja capaz de ouvir eventos de teclado. Este deve realizar alguma ao quando a tecla ENTER for pressionada sobre o campo.

36

Tratamento de Eventos

Espao para anotaes

37

Tratamento de Eventos

38

4. Componentes para Interface Grfica

Acesso a Banco de Dados

Objetivos
Apresentar os componentes mais utilizados em uma GUI Swing Entender a relao entre estes componentes Saber quando utilizar determinado componente Aprender como utilizar dois ou mais componentes em conjunto

Acesso a Banco de Dados

JFrame
Janelas em uma interface grfica so reas retangulares que podem ser exibidas em qualquer rea da tela. A classe JFrame responsvel pela exibio de janelas para o usurio (conforme ilustrao abaixo) com os recursos mnimos para sua utilizao. Como por exemplo, bordas, barra de ttulos, operaes de minimizar, maximizar, etc.

Figura 4-1: Exemplo de janela JFrame

Para que um JFrame seja exibido, propriedades bsicas devem ser definidas, como as suas dimenses, se estar visvel ou no entre outras. O programa abaixo mostra a criao de um JFrame definindo seu ttulo e dimenses.
package com.targettrust.java.capitulo04; import java.awt.event.*; import javax.swing.JFrame; public class JanelaPrincipal extends JFrame { public JanelaPrincipal() { setTitle( "Janela de Exemplo" ); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize( 400, 300 ); setVisible(true); } public static void main(String args[]) { JanelaPrincipal app = new JanelaPrincipal(); }

} Cdigo 4-1: Exemplo de utilizao de JFrame.

Acesso a Banco de Dados

O programa acima extende a classe JFrame, tendo como objetivo exibir uma janela na tela do usurio. O mtodo esttico main esta presente para que o programa possa ser executado. Apenas para relembrar, qualquer programa em uma aplicao Java Swing (que no seja applet) inicia sua execuo no mtodo esttico main. No mtodo main encontramos a seguinte: instruo new JanelaPrincipal(). Esta ser responsvel por criar uma nova instncia da classe JanelaPrincipal que um JFrame. A partir deste momento o construtor da classe ser executado e este ir configurar atravs de mtodos da classe JFrame como a mesma ser exibida. A primeira propriedade que o programa ira definir so as dimenses da Janela. Isto feito atravs de chamada ao mtodo setSize() da classe JFrame, este mtodo pode ser chamado recebendo como parmetro um objeto java.awt.Dimension ou diretamente com dois inteiros, o primeiro definindo a largura e o segundo a altura. Caso as dimenses no sejam definidas (mtodo setSize()), ser criada uma janela com dimenses nulas (zero de largura e zero de altura). Em seguida o ttulo ser definido com a chamada a setTitle();. Este mtodo ir definir como ttulo a String recebida como parmetro. Antes de a janela ser exibida, deve ser decidido o que o programa ir realizar quando for efetuada uma operao de fechar a janela. No AWT fazia-se necessrio implementar um evento com o cdigo responsvel pela operao de fechar a janela. No Swing foi criado um novo mtodo que pode realizar operaes padroes de fechamento. Para utilizar estas funes padro foi adicionado o mtodo setDefaultCloseOperation(). Este pode receber como parmetro as constantes da tabela abaixo:

DO_NOTHING_ON_CL OSE HIDE_ON_CLOSE

DISPOSE_ON_CLOSE EXIT_ON_CLOSE

No realiza nenhuma operao quando a janela for fechada. Automticamente oculta a janela quando esta for fechada atravs de uma chamada ao mtodo hide(). Automaticamente esconde e descarta a janela. Atravs de uma chamada ao mtodo dispose(). Termina a aplicao atravs do mtodo System.Exit(0).
4

Acesso a Banco de Dados Tabela 4-1: Operaes padres de fechamento de janela

No programa EXIT_ON_CLOSE.

exemplo,

foi

utilizada

mtodo

de

sada

padro

Neste ponto do programa, as propriedades bsicas para exibio de uma janela j esto definidas ento deve ser executada uma instruo para exibir a janela na tela atravs do mtodo show().

Acesso a Banco de Dados

JLabel

Os rtulos fornecem instrues de texto ou informaes sobre uma GUI. Os rtulos so definidos com a classe JLabel - uma subclasse de JComponent. Um rtulo exibe uma nica linha de texto de leitura. Uma vez que os rtulos so criados, os programas raramente alteram um contedo do rtulo.

package com.targettrust.java.capitulo04; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class LabelTest extends JFrame { private JLabel label1, label2, label3; public LabelTest() { super( "Testing JLabel" ); Container c = getContentPane(); c.setLayout( new FlowLayout() ); label1 = new JLabel( "Label com texto" ); label1.setToolTipText( "Tool tip de um label" ); c.add( label1 ); Icon javalogo = new ImageIcon(getClass().getResource("javalogo2.gif")); label2 = new JLabel("Label com texto e imagem", javalogo, SwingConstants.LEFT ); label2.setToolTipText( "Tool tip de um label" ); c.add( label2 ); label3 = new JLabel(); label3.setText( "Label com texto e icone abaixo" ); label3.setIcon( javalogo ); label3.setHorizontalTextPosition( SwingConstants.CENTER ); label3.setVerticalTextPosition( SwingConstants.BOTTOM ); c.add( label3 ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setSize( 275, 170 ); setVisible(true); {

public static void main( String args[] ) LabelTest app = new LabelTest(); } } Cdigo 4-2: Exemplo de utilizao de JLabel.

Acesso a Banco de Dados

O programa declara trs referncias JLabel. Os objetos JLabel so instanciados no construtor. A instruo new cria um objeto JLabel com o texto "Label with text". O texto exibido no rtulo automaticamente. O mtodo setToolTipText (herdada na classe JLabel da classe JComponent) especifica uma dica de ferramenta que exibida automaticamente quando o usurio posiciona o cursor do mouse sobre o rtulo na GUI. Quando executar esse programa, tente posicionar o mouse sobre cada rtulo para ver sua dica de ferramenta. O mtodo add adiciona label1 ao painel de contedo. Muitos componentes Swing podem exibir imagens especificando um cone como um argumento para seu construtor ou utilizando um mtodo que normalmente chamado de setIcon. Um Icon um objeto de qualquer classe que implementa a interface Icon (pacote javax.swing). Uma dessas classes ImageIcon (pacote javax.swing), que suporta dois formatos de imagem - Graphics Interchange Format (GIF) e Joint Photographic Experts Group (JPEG). Os nomes de arquivo para cada um desses tipos possuem extenes gif ou jpg (ou jpeg), respectivamente. O arquivo javalogo.gif contm a imagem para carregar e armazenar no objeto ImageIcon. Pressupe-se que esse arquivo esteja no mesmo diretrio que o programa. O objeto ImageIcon atribuido referncia Icon bug. Lembrese, a classe ImageIcon implementa a interface Icon, portanto um ImageIcon um Icon.

Figura 4-2: Exemplo de JLabel

A classe JLabel suporta a exibio de Icons. O construtor JLabel utilizado para criar um rtulo que exibe o texto "Label with text and icon" e o Icon que logojava referencia, e alinhado esquerda (isto , o icone e o texto esto o lado esquerdo da rea do rtulo na tela). A interface SwingConstants (pacote javax.swing) define um conjunto de constantes inteiras comuns (como SwingConstants LEFT) que so utilizadas com muitos componentes Swing. Por default, o texto aparece direita da imagem quando um rtulo contm tanto texto como imagem. Os alinhamentos horizontal e vertical de um rtulo podem ser configurados com os mtodos setHorizontalAlignment e setVerticalAligninent,
7

Acesso a Banco de Dados

respectivamente. A dica de ferramenta adicionada para label2 e adicionamos label2 ao painel de contedo. A classe JLabel fornece muitos mtodos para configurar um rtulo depois que ele foi instanciado. Cria-se um JLabel e invocamos o construtor sem argumentos (padro). Esse rtulo no tem texto ou Icon. Utiliza-se o mtodo JLabel setText para configurar o texto exibido no rtulo. Um mtodo correspondente getText recupera o texto atual exibido em um rtulo. Utilizamos um mtodo JLabel setIcon para configurar o Icon exibido no rtulo. Um mtodo correspondente getIcon recupera o Icon atual exibido em um rtulo. Utilizamos os mtodos JLabel setHorizontalTextPosition e setVerticalTextPosition para especificar a posio do texto no rtulo. As instrues precedentes indicam que o texto ser centralizado horizontalmente e aparecer na parte inferior do rtulo. Portanto, o Icon aparecer acima do texto.Configuramos o texto de dica de ferramenta para o label3 e aps adicionamos label3 ao painel de contedo.

Acesso a Banco de Dados

JButton
Um boto um componente em que o usurio clica para acionar uma ao especfica. Um programa Java pode utilizar vrios tipos de botes, incluindo botes de comando, caixas de seleo, botes de alternao e botes de opo. Consulte a documentao SDK na qual mostra a hierarquia de herana dos botes do Swing que abordaremos neste tem. Todos os tipos de boto so subclasses de AbstractButton (pacote javax.swing), o qual define muitos dos recursos que so comuns aos botes do Swing. Um boto de comando gera um ActionEvent quando o usurio clica no boto com o mouse. Os botes de comando so criados com a classe JButton, que herda da classe AbstractButton. O texto na face de um JButton chamado de rtulo de boto (caption). Uma GUI pode ter muitos JButtons, mas cada rtulo de boto em geral deve ser nico. O aplicativo abaixo cria dois JButtons e demonstra que JButtons (como JLabels) suportam a exibio de cones. O tratamento de eventos para os botes realizado por uma nica instncia de classe interna ButtonHandler.
package com.targettrust.java.capitulo04; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ButtonTest extends JFrame { private JButton plainButton, fancyButton; private class ButtonHandler implements ActionListener { public void actionPerformed( ActionEvent e ) { JOptionPane.showMessageDialog( null, "Voc pressionou: " + e.getActionCommand() ); } } public ButtonTest() { super( "Testando botes" ); Container c = getContentPane(); c.setLayout( new FlowLayout() ); plainButton = new JButton( "Boto sem cone" ); c.add( plainButton ); Icon bug1 = new ImageIcon( getClass().getResource("javalogo1.gif") ); Icon bug2 = new ImageIcon( getClass().getResource("javalogo2.gif") ); fancyButton = new JButton( "Fancy Button", bug1 ); fancyButton.setRolloverIcon( bug2 ); 9

Acesso a Banco de Dados

c.add( fancyButton ); ButtonHandler handler = new ButtonHandler(); fancyButton.addActionListener( handler ); plainButton.addActionListener( handler ); pack(); setVisible(true);

public static void main( String args[] ) { ButtonTest app = new ButtonTest(); } } Cdigo 4-3: Exemplo de utilizao de JButton.

Declaramos duas referncias para as instncias de classe JButton plainButton e fancyButton (que so instanciadas no construtor). Criamos plainButton com o rtulo de boto PlainButton e adicionamos o boto ao painel de contedo. Um JButton pode exibir cones. Para fornecer ao usurio um nvel extra de interatividade visual com a GUI, um JButton tambm pode ter um cone rollover, ou seja, um cone que exibido quando o mouse posicionado sobre o boto. O cone no boto altera-se quando o mouse se move para dentro e para fora da rea do boto na tela. Criamos dois objetos ImageIcon que representam o Icon padro e o Icon rollover para o JButton criado. Ambas as instrues pressupem que os arquivos de imagem so armazenados no mesmo diretrio que o programa (que geralmente o caso para aplicativos que utilizam imagens). Criamos fancyButton com texto-padro Fancy Button e o Icon bug1. Por default, o texto exibido direita do cone. Utilizamos o mtodo setRolloverIcon (herdado da classe AbstractButton na classe JButton) para especificar a imagem exibida no boto quando o usurio posiciona o mouse sobre o boto. Adicionamos o boto ao painel de contedo.

Figura 4-3: Exemplo de JButton 10

Acesso a Banco de Dados

JButtons (como JTextFields) geram ActionEvents. Como mencionado anteriormente, um ActionEvent pode ser processado por qualquer objeto ActionListener. Registramos um objeto ActionListener para cada JButton. A classe interna ButtonHandler define actionPerformed para exibir um caixa de dilogo de mensagem contendo o rtulo para o boto que foi pressionado pelo usurio. O mtodo ActionEvent getActionCommand retoma o rtulo do boto que gerou o evento.

11

Acesso a Banco de Dados

JTextField e JPasswordField

JTextFields e JPasswordFields (pacote javax.swing) so reas de uma nica linha em que o texto pode ser inserido via teclado pelo usurio ou o texto pode ser simplesmente exibido. Um JPasswordField mostra que um caractere foi digitado quando o usurio insere os caracteres, mas oculta os caracteres assumindo que eles representam uma senha que deve permanecer conhecida apenas para o usurio. Quando o usurio digita os dados em um JTextField ou JPasswordField e pressiona a tecla Enter, um evento de ao ocorre. Se um ouvinte de evento registrado, o evento processado e os dados no JTextField ou JPasswordField podem ser utilizados no programa. A classe JTextField estende a classe JTextComponent (pacote javax.swing.text), que fornece muitos recursos comuns para os componentes baseados em texto do Swing. A classe JPasswordField estende JTextField e adiciona vrios mtodos que so especificos ao processamento de senhas. O aplicativo de exemplo utiliza as classes JTextField e JPasswordField para criar e manipular quatro campos. Quando o usurio pressiona Enter no campo atualmente ativo (o componente atualmente ativo "tem o foco"), uma caixa dilogo de mensagem contendo o texto no campo exibida. Quando um evento ocorre no JPasswordField, a senha revelada.
package com.targettrust.java.capitulo04; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TextFieldTest extends JFrame { private JTextField text1, text2, text3; private JPasswordField password; public TextFieldTest() { super( "Testando JTextField e JPasswordField" ); Container c = getContentPane(); c.setLayout( new FlowLayout() ); text1 = new JTextField( 10 ); c.add( text1 ); text2 = new JTextField( "Digite um texto aqui: " ); c.add( text2 );

12

Acesso a Banco de Dados text3 = new JTextField( "Campo no editvel", 20 ); text3.setEditable( false ); c.add( text3 ); password = new JPasswordField( "Sua senha" ); c.add( password ); TextFieldHandler handler = new TextFieldHandler(); text1.addActionListener( handler ); text2.addActionListener( handler ); text2.addMouseListener( handler ); text3.addActionListener( handler ); addMouseWheelListener(handler); password.addActionListener( handler ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setSize( 325, 100 ); setVisible(true); } public static void main( String args[] ) { TextFieldTest app = new TextFieldTest(); } private class TextFieldHandler implements ActionListener, MouseListener, MouseWheelListener { public void actionPerformed( ActionEvent e ) { String s = ""; if ( e.getSource() == text1 ) s = "text1: " + e.getActionCommand(); else if ( e.getSource() == text2 ) s = "text2: " + e.getActionCommand(); else if ( e.getSource() == text3 ) s = "text3: " + e.getActionCommand(); else if ( e.getSource() == password ) { s = "password: " + e.getActionCommand(); } } JOptionPane.showMessageDialog( null, s );

public void mouseClicked(MouseEvent e) { text2.setText(""); } public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseWheelMoved(MouseWheelEvent e) { JOptionPane.showMessageDialog( null, "Wheel!!!!" ); } 13

Acesso a Banco de Dados } } Cdigo 4-4: Exemplo de utilizao de JTextField e JPasswordField.

So declaradas trs referncias a JTextFields (text1, text2 e text3) e um JPasswordField (password). Cada uma delas instanciada no construtor. Defnimos JTextField text1 com 10 colunas de texto. A largura do campo de texto ser a largura em pixels do caractere mdio na fonte atual do campo de texto multiplicado por 10. Adicionamos text1 ao painel de contedo. Definimos JTextField text2 com o texto inicial "Enter text here" para exibir no campo de texto. A largura do campo de texto determinada pelo texto. Adicionamos text2 ao painel de contedo. Definimos JTextField text3 e chamamos o construtor JTextField com dois argumentos - o texto-padro "Uneditable textfield" para exibir no campo de texto e o nmero de colunas (20).A largura do campo de texto determinada pelo nmero de colunas especificadas.

Figura 4-4: Exemplo de JTextField e JPasswordField

Utilizamos o mtodo setEditable (herdado no JTextField da classe JTextComponent) para indicar que o usurio no pode modificar o texto no campo de texto. Adicionamos text3 ao painel de contedo. Definimos JPasswordField password com o texto "Hidden text" para exibir no campo de texto. A largura do campo de texto determinada pelo texto. Repare que o texto exibido como uma string de asteriscos quando o programa executa. Adicionamos password ao painel de contedo. Para o tratamento de eventos nesse exemplo, definimos a classe interna TextFieldHandler. O tratador da classe JTextField (discutido em detalhe brevemente) implementa a interface ActionListener. Portanto, cada instncia da classe TextFieldHandler um ActionListener.
14

Acesso a Banco de Dados

Definimos uma instncia da classe TextFieldHandler e a atribui referencia handler. Essa instncia ser utilizada como o objeto ouvinte de eventos para os JTextFields e o JPasswordField nesse exemplo. Aps instrues de registro de evento que especificam o objeto ouvinte de eventos para cada um dos trs JTextFields e para o JPasswordField so especificadas. Depois que essas instrues executam, o objeto que handler referencia est ouvindo eventos (isto , ser notificado quando um evento ocorrer) nesses quatro objetos. Em cada caso, o mtodo addActionListener da classe JTextField chamado para registrar o evento. O mtodo addActionListener recebe como seu argumento um objeto ActionListener. Portanto, qualquer objeto de uma classe que implemente a interface ActionListener (isto , qualquer objeto que um ActionListener ) pode ser fornecido como um argumento para esse mtodo. O objeto que handler referencia um ActionListener porque sua classe implementa a interface ActionListener. Agora, quando o usurio pressiona Enter em qualquer desses quatro campos, o mtodo actionPerformed na classe TextFieldHandler chamado para tratar o evento. O mtodo actionPerformed utiliza seu mtodo ActionEvent do argumento getSource para determinar o componente GUI com o qual o usurio interagiu e cria um String para exibir em uma caixa de dilogo de mensagem. O mtodo ActionEvent getActionCommand retorna o texto no JTextField que gerou o evento. Se o usurio interagiu com o JPasswordField, Instrues realizam a coero da referncia de Component retornada por e.getSource() para uma referncia JPasswordField de modo utilizamos o mtodo JPasswordField getPassword para obter a senha e criar o String a ser exibido. O mtodo getPassword retorna a senha como um array de tipo char que utilizado como um argumento para um construtor de String para criar um String. Exibimos uma caixa de mensagem indicando o nome de referncia do componente GUI e o texto que o usurio digitou no campo. Observe que mesmo um JTextField no editvel pode gerar um evento. Tambm observe que o texto real da senha exibido quando se pressiona Enter no JPasswordField ( claro que normalmente voc no faria isso!) Utilizar uma classe separada para definir um ouvinte de eventos uma prtica de programao comum para separar a interface GUI da implementao de seu tratador de evento.

15

Acesso a Banco de Dados

JTextArea

A classe JTextArea destinada a exibir uma rea para manipulao de mltiplas linhas de texto. Da mesma forma que a classe JTextField, esta classe herda JTextComponent.
package com.targettrust.java.capitulo04; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TextAreaTest extends JFrame { private String texto2; private String texto; private JTextArea txtArea1; private JTextArea txtArea2; private Container c; public TextAreaTest() { texto2 = new String(""); texto = new String("Digite aqui"); txtArea1 = new JTextArea(texto, 10, 15); txtArea2 = new JTextArea(texto2, 10, 15); c = getContentPane(); // Define o gerenciador de layout a ser utilizado e suas propriedades FlowLayout layout = new FlowLayout(); c.setLayout(layout); layout.setAlignment(FlowLayout.LEFT); // Define as propriedades da janela que sera exibida setSize( 400, 300 ); setTitle("Utilizando JTextArea"); // Define a operacao padrao para fechamento (encerrar programa) setDefaultCloseOperation(EXIT_ON_CLOSE); // Cria a JTextArea 1 c.add(txtArea1); // Adiciona barra de rolagem na JTextArea getContentPane().add(new JScrollPane(txtArea1)); // Adiciona o botao de copiar somente o texto selecionado JButton copiarSelecionado = new JButton("Copiar Selecionado"); c.add(copiarSelecionado); // Adiciona o botao de copiar todo o texto selecionado JButton copiarTudo = new JButton("Copiar Tudo"); c.add(copiarTudo); // Cria a JTextArea 2 c.add(txtArea2); 16

Acesso a Banco de Dados // Adiciona barra de rolagem na JTextArea c.add(new JScrollPane(txtArea2)); // Adiciona os eventos aos botoes copiarTudo.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { txtArea2.setText(txtArea1.getText()); } } ); copiarSelecionado.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { txtArea2.setText(txtArea1.getSelectedText()); } } ); // Exibe a janela na tela setVisible(true);

public static void main(String args[]) { TextAreaTest app = new TextAreaTest(); } } Cdigo 4-5: Exemplo de utilizao de JTextArea.

O programa acima exemplifica a utilizao de um JTextArea atravs da criao de um programa simples que exibe duas caixas de texto (JTextArea) na tela e dois botes (JButton). Os botes no exemplo permitem duas operaes. O primero boto chamado Copiar Tudo quando clicado ira copiar o texto digitado na primeira JTextArea para a segunda JTextArea. O segundo boto chamado Copiar Selecionado quando acionado ir copiar somente o texto selecionado na primeira JTextArea para a segunda JTextArea. A imagem abaixo mostra a tela do programa exemplo:

17

Acesso a Banco de Dados

Figura 4-5: Imagem da tela do programa de exemplo de JTextArea.

No programa, declaramos duas JTextArea, uma chamada txtArea1, e outra chamada txtArea2. Instanciamos as duas atravs da operao new JTextArea() que recebe como parmetro o texto inicial da caixa de texto, o nmero de linhas e o nmero de colunas. Inicializamos a txtArea1 com o texto Digite aqui e a caixa txtArea2 sem texto inicial. O programa adiciona a as duas caixas de texto uma barra de rolagem (JScrollPane). Alm disso, so criados dois botes (conforme j visto no tpico sobre JButton) os quais ao serem clicados realizam diferentes operaes. Ambos os botes inserem texto na segunda JTextArea atravs do mtodo setText. Para realizar esta operao (definir o texto da segunda JTextArea objeto txtArea2) o primeiro boto (Copiar Tudo) realiza uma chamada ao mtodo getText() da primeira JTextArea (objeto txtArea1) copiando desta forma todo o texto da primeira para a segunda caixa de texto. J o segundo boto, utiliza-se do mtodo getSelectedText() para copiar apenas o texto selecionado da primeira para a segunda caixa de texto.

A tabela abaixo exibe alguns mtodos teis e sua funo na classe JTextArea. insert(String str, int pos) replaceRange(String str, int start, int end) setTabSize(int size) setFont(Font f) Insere o texto na posio expecificada. Substitui o texto pelo informado no primeiro parmetro, da posio inicial at a final. Define o tamanho da tabulao (quando pressionado a tecla TAB). Define a fonte utilizada na caixa de texto.

Tabela 4-2: Mtodos principais da classe JTextArea.

18

Acesso a Banco de Dados

JPanel

Ao desenvolver interfaces mais complexas, cada componente dever ser colocado em um local exato para que a aplicao fique com uma GUI interessante para o usurio. Para conseguir localiza-los em posies exatas, torna-se necessria a utilizao de reas ou grupos de componentes. Estes so chamados de painis. Os painis so controlados pela classe JPanel que uma subclasse de JComponent. Resumindo, um painel um agrupamento de componentes, sendo que estes componentes podem ser at mesmo outros painis.

Figura 4-6: Exemplo de utilizao de JPanel.

Na imagem acima verificamos a utilizao de um JPanel, esta GUI mostra a utilizao de dois painis com dois diferentes gerenciadores de layout. O primeiro painel utilizando BorderLayout e o segundo utilizando GridLayout.
package com.targettrust.java.capitulo04; import java.awt.*; import javax.swing.*; public class Paineis extends JFrame { public Paineis() { 19

Acesso a Banco de Dados getContentPane().setLayout(new BorderLayout()); JPanel painelGrid = new JPanel(); GridLayout layout = new GridLayout(1, 3); painelGrid.setLayout(layout); setTitle("Exemplo de Paineis"); JButton esquerda = new JButton("Esquerda"); JButton meio = new JButton("Meio"); JButton direita = new JButton("Direita"); painelGrid.add(esquerda); painelGrid.add(meio); painelGrid.add(direita); getContentPane().add(painelGrid, BorderLayout.SOUTH); setSize( 400, 300 ); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); } public static void main(String args[]) { Paineis app = new Paineis(); } } Cdigo 4-6: Utilizao de painis com JPanel.

No programa acima, a primeira linha do construtor modifica o painel padro do JFrame para um BorderLayout atravs do mtodo getContentPane().setLayout(). Este procedimento define o primeiro gerenciador de layout a ser utilizado no primeiro painel. Logo em seguida realizada a declarao de um novo painel utilizando-se da classe JPane e tambm definido um novo gerenciador de layout o GridLayout e aps as duas declaraes associado ao segundo painel o GridLayout. So instanciados quatro objetos, trs botes e uma caixa de texto. Os botes so adicionados ao segundo painel atravs do mtodo add() do painel, j a caixa de texto associada ao primeiro painel atravs do mesmo mtodo. Ao final o segundo painel (contendo os botes) adicionado na regio sul do primeiro painel atravs do mtodo add(), com isso faz com que a caixa de texto expanda-se por toda a regio norte do primeiro painel.

20

Acesso a Banco de Dados

JComboBox
Uma caixa de combinao (ou combo box, s vezes tambm chamada de lista drop-down) fornece uma lista de itens entre os quais o usurio pode escolher. As caixas de combinao so implementadas com a classe JComboBox, que herda da classe JComponent. JComboBoxs geram ItemEvents como JCheckBoxs e JRadioButtons.
package com.targettrust.java.capitulo04; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ComboBoxTest extends JFrame { private JComboBox images; private JLabel label; private String names[] = {"img1.gif", "img2.gif", "img3.gif", "img4.gif"}; private Icon icons[] = { new ImageIcon( getClass().getResource(names[ 0 ] ) ), new ImageIcon( getClass().getResource(names[ 1 ] ) ), new ImageIcon( getClass().getResource(names[ 2 ] ) ), new ImageIcon( getClass().getResource(names[ 3 ] ) ) }; public ComboBoxTest() { super( "JComboBox" ); Container c = getContentPane(); c.setLayout( new FlowLayout() ); images = new JComboBox( names ); images.setMaximumRowCount( 3 ); images.addItemListener( new ItemListener() { public void itemStateChanged( ItemEvent e ) { label.setIcon( icons[ images.getSelectedIndex() ] ); } } ); c.add( images ); label = new JLabel( icons[ 0 ] ); c.add( label ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setSize( 350, 100 ); setVisible(true); } public static void main( String args[] ) { ComboBoxTest app = new ComboBoxTest(); }

} Cdigo 4-7: Exemplo de utilizao de JComboBox.

21

Acesso a Banco de Dados

Atravs deste exemplo podemos verificar a utilizao de um JComboBox a fim de fornecer uma lista de quatro nomes de arquivo de imagem. Quando um nome de arquivo de imagem selecionado, a imagem correspondente exibida como um Icon em um JLabel. Declaramos e inicializamos o array de cones de com quatro novos objetos ImageIcon. O array String names contm os nomes dos quatro arquivos de imagem que so armazenados no mesmo diretrio que o aplicativo. Criamos um objeto JComboBox utilizando os Strings no array names como os elementos na lista. Um ndice numrico monitora a ordem de itens na JComboBox. O primeiro item adicionado no ndice 0; o prximo item adicionado no ndice 1, etc. O primeiro item adicionado a uma JComboBox aparece como o item atualmente selecionado quando a JComboBox exibida. Outros itens so selecionados clicando na JComboBox. Quando clicada, a JComboBox expande em uma lista na qual o usurio pode fazer uma seleo. Utilizamos o mtodo JComboBox setMaximumRowCount para estabelecer o nmero mximo de elementos que so exibidos quando o usurio clica na JComboBox. Se houver mais itens na JComboBox que o nmero mximo de elementos que so exibidos, a JComboBox fornece automaticamente uma barra de rolagem que permite ao usurio visualizar todos os elementos na lista.

Figura 4-7: Exemplo de JComboBox

O usurio pode clicar nas setas de rolagem na parte superior e inferior da barra de rolagem para mover-se para cima e para baixo pela lista, um elemento por vez, ou o usurio pode arrastar a caixa de rolagem no meio da barra de rolagem para cima e para baixo para mover-se pela lista. Para arrastar a caixa de rolagem, mantenha o boto do mouse pressionado com o cursor de mouse na caixa de rolagem e mova o mouse. Registramos uma instncia de uma classe interna annima que implementa ItemListener como o ouvinte para JComboBox images. Quando o usurio faz uma seleo de imagens, o mtodo itemStateChanged configura o
22

Acesso a Banco de Dados

Icon como label. O Icon selecionado do array icons determinando o nmero do ndice do item selecionado no JComboBox atravs do mtodo getSelectedlndex.

23

Acesso a Banco de Dados

Construindo Menus
Em qualquer GUI os menus so fundamentais, pois permitem ao usurio realizar aes sem deixar uma tela confusa com muitos itens ou botes descnecessrios. Os menus se dividem em dois tipos bsicos, as barras de menu e os menus popup ou menus de contexto.

24

Acesso a Banco de Dados

Barras de Menus (JMenuBar)


A classe JMenuBar tem por objetivo gerenciar uma barra de menus. Uma barra de menus comumente utilizada em aplicaes, estando localizada abaixo do ttulo da janela. No Swing uma barra de menu somente podem ser associados a classes que possuam o mtodo setJMenuBar, as classes em que mais comumente utilizamos menus so JFrame e JApplet. A ilustrao abaixo exemplifica o funcionamento dos objetos de menu:

Figura 4-8: Classes utilizadas em uma barra de menus.

Conforme verificamos na ilustrao acima, temos um primeiro crculo delimitando uma rea JMenuBar. Esta rea o espao para o menu, ou seja esta classe quem indica qual vai ser o tipo do menu, neste caso uma barra de menu. Logo em seguida verificqmos um indicativo para a classe JMenu, esta classe responsvel por agrupar itens de um menu como no exemplo acima agrupar as cores do texto ou as funes de arquivo. Um menu no necessariamente precisa de uma classe JMenu, pode-se associar diretamente os itens a JMenuBar. Esta classe pode ser utilizada em todos os tipos de menus no ficando restrita apenas as barras como veremos mais a frente. Dentro dos grupos de menu (JMenu) esto colocados os itens (JMenuItem), esta a parte funcional e programvel do menu, ou seja estes so os objetos que so a pondo final do menu, fazendo uma analogia a uma rvore, os itens seriam as folhas.
25

Acesso a Banco de Dados

Os itens de menu podem derivar de dois outros tipos tambm, JCheckBoxMenuItem e JRadioButtonMenuItem, estes responsveis por exibirem um item radio ou check no menu conforme veremos a frente.

Segue o cdigo fonte exemplo que foi utilizado para construo da tela acima:
package com.targettrust.java.capitulo04; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ExemploMenu extends JFrame { JMenuBar barra = new JMenuBar(); JLabel texto = new JLabel(); public ExemploMenu() { FlowLayout layout = new FlowLayout(); layout.setAlignment(FlowLayout.CENTER); getContentPane().setLayout(layout); setTitle("Exemplo de JMenuBar, JMenu e JMenuItem"); setSize( 400, 300 ); setDefaultCloseOperation(EXIT_ON_CLOSE); JMenu arquivo = new JMenu("Arquivo"); arquivo.setMnemonic('A'); JMenuItem sair = new JMenuItem("Sair"); arquivo.add(sair); barra.add(arquivo); JMenu cor = new JMenu("Cor do Texto"); cor.setMnemonic('C'); JMenuItem azul = new JMenuItem("Azul"); JMenuItem vermelho = new JMenuItem("Vermelho"); JMenuItem verde = new JMenuItem("Verde"); cor.add(azul); cor.add(vermelho); cor.add(verde); barra.add(cor); setJMenuBar(barra); texto.setText("Curso Java"); texto.setSize(100, 14); texto.setForeground(Color.BLUE); getContentPane().add(texto); // Continua na prxima pgina azul.addActionListener( 26

Acesso a Banco de Dados new ActionListener() { public void actionPerformed(ActionEvent e) { texto.setForeground(Color.BLUE); } } ); vermelho.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { texto.setForeground(Color.RED); } } ); verde.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { texto.setForeground(Color.GREEN); } } ); sair.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } } ); } setVisible(true);

public static void main(String args[]) { ExemploMenu app = new ExemploMenu(); } } Cdigo: 4-8: Construindo uma barra de menus.

No programa acima, a primeira ao realizada a criao de uma instncia de JMenuBar chamada barra. Este objeto ser o agregador de todos os itens filhos do menu. No construtor so criados novos objetos chamados arquivo e cor. Estes sero os agrupadores (os dois grupos de menus). Ou seja, sero os itens que ficaram visveis na barra logo que o programa for executado. Estes recebem como parmetro na sua construo o nome a ser exibido ou o Label. Aps criar estes objetos, realizada uma chamada ao mtodo setMnemonic() da classe JMenu, o qual definir qual ser a letra da palavra que servir como atalho para este menu (exemplo Arquivo, a vogal A a letra ou tecla de atalho para este menu). Na seqncia so criados objetos JMenuItem que sero os itens do menu efetivamente, estes recebem como parmetro em sua contruo o nome a ser exibido.

27

Acesso a Banco de Dados

Aps os itens do menu criados, o programa realiza a associao destes itens a seus grupos, atravs do mtodo add() da classe JMenuItem(), como exemplo cor.add(azul), onde cor o JMenu e azul o JMenuItem, em outras palavras feita a ligao do item como menu (grupo). Da mesma forma como feita esta relao, tambm deve-se associar os JMenus a barra de menus (JMenuBar) e isto feito atravs do mtodo add() da classe JMenuBar, por exemplo barra.add(cor), onde efeivamente feita a ligao do JMenu (cor) a JMenuBar (barra). Neste ponto os menus esto configurados e relacionados, ento so adicionados ao JFrame atravs do mtodo setJMenuBar(barra) e finalmente executado o mtodo show() do JFrame para que seja exibido o programa em tela. Resumindo a montagem do menu. Os menus so associados em cascata, ou seja, associa-se o item ao grupo que pode estar relacionado a outro grupo com outros itens e assim sucesivamente at chegar barra de menus. Agora o programa comea a associar funcionalidade aos botes e esta feita atravs de implementao de cdigo nos mtodos addActionListner() da classe JMenuItem. Os JMenuItems do grupo cor (Cor do Texto) possuem todos o mesmo cdigo fonte, modificando a cor do JLabel da tela para a cor clicada atravs dp mtodo setForeground da classe JLabel. O nico JMenuItem com implementao diferente o Sair que efetua uma chamada a System.exit() encerrando a aplicao.

28

Acesso a Banco de Dados

Utilizando JRadioButtonMenuItem
Conforme citado acima, podemos tambm utilizar itens radio na construo de menus para gerar uma situao como a da figura abaixo:

Figura 4-9: Exemplo de utilizao de JRadioButtonMenuItem.

Segue abaixo o cdigo exemplo:


package com.targettrust.java.capitulo04; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ExemploMenuRadioButton extends JFrame { JMenuBar barra = new JMenuBar(); public ExemploMenuRadioButton() { FlowLayout layout = new FlowLayout(); layout.setAlignment(FlowLayout.CENTER); getContentPane().setLayout(layout); setTitle("Exemplo de JMenuBar, JMenu e JMenuItem"); JMenu cores = new JMenu("Cores");

ButtonGroup grupo = new ButtonGroup(); JRadioButtonMenuItem azul = new JRadioButtonMenuItem("Azul"); JRadioButtonMenuItem verde = new JRadioButtonMenuItem("Verde"); JRadioButtonMenuItem vermelho = new JRadioButtonMenuItem("Vermelho"); grupo.add(azul); 29

Acesso a Banco de Dados grupo.add(verde); grupo.add(vermelho); cores.add(azul); cores.add(verde); cores.add(vermelho); barra.add(cores); setJMenuBar(barra); setSize( 400, 300 ); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true);

public static void main(String args[]) { ExemploMenuRadioButton app = new ExemploMenuRadioButton(); } } Cdigo 4-9: Criando menus com JRadioButtonMenuItem.

O programa exemplo acima semelhante ao programa exibido anteriormente, desta forma neste tpico ser dado enfoque as reas diferentes deste cdigo. A primeira ao para construo de um JRadioButtonMenuItem a criao de um grupo de botes. Este grupo tem por funo dizer quais so os itens que estaro inclusos no radio para fins de restringir que exista apenas um item selecionado do mesmo grupo. A criao deste grupo feita atravs do objeto grupo, instanciado a partir da classe ButtonGroup. Na seqncia so criados os itens de JRadioButtonMenuItem efetivamente, declarando os objetos azul, verde e vermelho. Aps a declarao destes itens, os mesmos so associados ao grupo de botes e aps associados ao JMenu. Este cdigo far com que sejam exibidos trs itens radio no menu permitindo a seleo de apenas um destes.

30

Acesso a Banco de Dados

JCheckBoxMenuItem
Conforme citado acima, podemos tambm utilizar itens check na construo de menus para gerar uma situao como a da figura abaixo:

Figura 4-10: Exemplo de utilizao de JCheckBoxMenuitem.

Segue abaixo o cdigo de exemplo:


package com.targettrust.java.capitulo04; import java.awt.*; import javax.swing.*; public class ExemploMenuCheckBox extends JFrame { JMenuBar barra = new JMenuBar(); public ExemploMenuCheckBox() { FlowLayout layout = new FlowLayout(); layout.setAlignment(FlowLayout.CENTER); getContentPane().setLayout(layout); setTitle("Exemplo de JMenuBar, JMenu e JMenuItem"); JMenu estilo = new JMenu("Estilo da Fonte");

JCheckBoxMenuItem negrito = new JCheckBoxMenuItem("Negrito"); JCheckBoxMenuItem italico = new JCheckBoxMenuItem("Italico"); JCheckBoxMenuItem sublinhado = new JCheckBoxMenuItem("Sublinhado"); estilo.add(negrito); estilo.add(italico); 31

Acesso a Banco de Dados estilo.add(sublinhado); barra.add(estilo); setSize(400, 300); setDefaultCloseOperation(EXIT_ON_CLOSE); setJMenuBar(barra); } setVisible(true);

public static void main(String args[]) { ExemploMenuCheckBox app = new ExemploMenuCheckBox(); } } Cdigo 4-10: Criando menus com JCheckBoxMenuItem.

O programa exemplo acima funciona exatamente do mesmo modo que os programas explicados nos tpicos anteriores tendo como nica diferena a substituio dos itens JMenuItem por JCheckBoxMenuItem.

32

Acesso a Banco de Dados

JPopupMenu

A classe JPopupMenu responsvel pela exibio de pequenos menus (menus de contexto) os quais so muito utilizados nos atuais programas de computador. No Swing so exibidos ao receberem o gatilho pop-up que geralmente disparado com o clicar do boto direito do mouse. Para ilustrar a explicao acima segue a seguinte imagem de um JPopupMenu:

Figura 4-11: Exemplo de utilizao de JPopupMenu.

No programa abaixo exibido o cdigo fonte que originou a imagem:


package com.targettrust.java.capitulo04; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class PopupMenu extends JFrame implements ActionListener { private JPopupMenu popupMenu; public PopupMenu() { setTitle("Exemplo de JPopupMenu"); getContentPane().setLayout(null); JMenuItem JMenuItem JMenuItem JMenuItem menuFileNovo = new JMenuItem("Novo"); menuFileAbrir = new JMenuItem("Abrir"); menuFileSalvar = new JMenuItem("Salvar"); menuFileSair = new JMenuItem("Sair");

popupMenu = new JPopupMenu( "Menu" ); popupMenu.add(menuFileNovo); popupMenu.add(menuFileAbrir); popupMenu.add(menuFileSalvar); popupMenu.addSeparator(); popupMenu.add(menuFileSair); 33

Acesso a Banco de Dados getContentPane().add(popupMenu); // Continua na prxima pgina enableEvents(AWTEvent.MOUSE_EVENT_MASK); menuFileNovo.addActionListener(this); menuFileAbrir.addActionListener(this); menuFileSalvar.addActionListener(this); menuFileSair.addActionListener(this); setSize(400, 200); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); } public void processMouseEvent( MouseEvent event ) { if(event.isPopupTrigger() ) { popupMenu.show(event.getComponent(), event.getX(), event.getY()); } super.processMouseEvent(event); } public void actionPerformed( ActionEvent event ) { String item = event.getActionCommand(); if(item.equals("Novo")) { JOptionPane.showMessageDialog(getContentPane(), "Voc clicou em Novo"); } else if(item.equals("Abrir")) { JOptionPane.showMessageDialog(getContentPane(), "Voc clicou em Abrir"); } else if(item.equals("Salvar")) { JOptionPane.showMessageDialog(getContentPane(), "Voc clicou em Salvar"); } else if(item.equals("Sair")) { System.exit(0); } } public static void main(String args[]) { PopupMenu mainFrame = new PopupMenu(); } } Cdigo 4-11: Exemplo de utilizao de JPopupMenu

No programa acima declarado um objeto popupMenu a partir da classe JPopupMenu. Este objeto ser o menu efetivamente. Logo em seguida, no construtor so declarados quatro objetos JMenuItem, objetos estes que sero os itens do menu e que recebem como parmetro em sua construo o seu texto de exibio. Tendo o programa declarado o JPopupMenu e associar os itens ao menu, isto feito atravs JPopupMenu (objeto popupMenu). Note que addSeparator() enrtre o terceiro e o quarto item, um separador (uma linha entre os menus). seus itens, o prximo passo do mtodo add() da classe existe uma chamada a esta utilizada para exibir
34

Acesso a Banco de Dados

Declarados os objetos e feita a ligao entre o menu e seus itens, o programa adiciona o menu ao painel padro do JFrame atravs do mtodo getContentPane.add(). Neste ponto o menu esta montado e j exibido em tela, agora o programa parte para o controle dos eventos que podem ser gerados pelo menu. Prestando ateno ao incio do cdigo visualizado que o programa implementa a interface ActionListener (ver captulo sobre controle de eventos), e portanto implementa o mtodo actionPerformed(). Este mtodo executado a cada novo evento gerado, como por exemplo clicar com o mouse sobre um dos itens do menu. O mtodo actionPerformed() recebe como parmetro o objeto ActionEvent e atravs da propriedade getActionCommand() deste, encontra qual boto foi clicado. Para cada boto exibe uma caixa de dilogo com o nome da opo que originou o evento, exceto ao clicar em sair onde executado um System.exit(0) terminando a aplicao.

35

Acesso a Banco de Dados

Entendendo as Caixas de Dilogo

Janelas de dilogos so janelas utilizadas para fazer interao com o usurio, todas as janelas de dilogo partem de um Frame, ou seja, toda vez que o frame que esta mantendo aquela janela de dilogo destrudo, os dilogos vinculados a ele tambm so, cada vez que Frame minimizado, os dilogos desaparecem da tela. Os dilogos podem ser modais ou no, um dilogo modal aquele em que quando exibido bloqueia o Frame que o mantem, em outras palavras impede que o usurio saia do foco dele para a qualquer outra janela do programa. Todos os dilogos que utilizamos no Swing derivam da classe JDialog que tem sua origem na java.awt.Dialog. Normalmente os programas Swing no utilizam diretamente a classe JDialog e sim a subclasse JOptionPane, a qual j oferece uma soluo de mais fcil utilizao para trabalhar com diversos tipos de dilogo.

36

Acesso a Banco de Dados

JOptionPane

Conforme j explicado na subseo anterior, para construir caixas de dilogo, normalmente utilizada a classe JOptionPane. Todos os dilogos gerados atravs desta classe so modais. Para construir dilogos no modais, deve ser utilizado diretamente a classe JDialog. A classe JOptionPane possui mtodos para gerar os tipos de dilogos mais comumente utilizados. Qualquer dialogo criado com JOptionPane possui um conjunto de cones padres que podem ser utilizados a fim de preservar o Look And Feel de cada plataforma, cones customizados tambm podem ser adicionados quando necessrio.

Figura 4-12: cones padro do JOptionPane.

Para exibir uma caixa de dilogo simples com um texto e um boto de OK, deve-se utilizar o mtodo JOptionPane.showMessageDialog() conforme segue:

Figura 4-13: Caixa de dilogo utilizando showMessageDialog().

package com.targettrust.java.capitulo04; import javax.swing.*; import java.awt.Dimension; public class Dialogo extends JFrame { public Dialogo() { setTitle("Exemplo de Dialogo"); setDefaultCloseOperation(EXIT_ON_CLOSE); 37

Acesso a Banco de Dados setSize(400, 300); setVisible(true); JOptionPane.showMessageDialog(getContentPane(), "Mensagem de teste", "Titulo da mensagem", JOptionPane.INFORMATION_MESSAGE);

public static void main(String args[]) { Dialogo app = new Dialogo(); } } Cdigo 4-12: Cdigo fonte para construo de um dilogo utilizando showMessageDialog().

No programa acima importante destacar os parmetros para chamada do mtodo esttico showMessageDialog(): WARNING_MESSAGE ERROR_MESSAGE INFORMATION_MESSAGE PLAIN_MESSAGE Mensagem com cone de ateno do Look And Feel da plataforma. Mensagem com cone de erro do Look And Feel da plataforma. Mensagem com cone de mensagem do Look And Feel da plataforma. Mensagem sem cone

Tabela 3-3: Tipos de mensagem.

Component parentComponent Object message String title int messageType Icon icon

Frame de referncia, a janela ou o frame onde ficar associado o dilogo. Mensagem a ser exibida no dilogo, pode ser uma String ou at mesmo um painel contendo imagens, etc. Define o ttulo da janela de dilogo. Tipo da mensagem a ser exibida, informao, aviso, erro, etc. (conforme tabela 3-3). cone da mensagem, este utilizado para JOptionPane com cones personalizados independentes do Look And Feel.

Tabela 4-4: Parmetros do mtodo showMessageDialog().

Para exibir uma caixa de dialogo com opes de confirmao podemos utilizar o mtodo showConfirmDialog(), conforme exemplo abaixo:

38

Acesso a Banco de Dados Figura 4-13: Caixa de dilogo utilizando JConfirmDialog().

Segue o cdigo fonte utilizado:


package com.targettrust.java.capitulo04; import java.awt.Dimension; import javax.swing.*; public class ConfirmDialog extends JFrame { public ConfirmDialog() { setTitle("Exemplo de Dialogo"); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(400, 300); show(); JOptionPane.showConfirmDialog(getContentPane(), "Confirma?"); } public static void main(String args[]) { ConfirmDialog app = new ConfirmDialog(); }

} Cdigo: 4-13: Exibindo um JConfirmDialog.

Consulte a API do SDK para conhecer maiores variaes deste mtodo. Para exibir uma caixa de dilogo JOptionPane personalizada esta disponvel o mtodo showOptionDialog():

Figura 4-14: Utilizando JOptionDialog().

package com.targettrust.java.capitulo04; import java.awt.Dimension; import javax.swing.*; public class OptionDialog extends JFrame { private Object[] options = {"Sair sem salvar", "Salvar e sair", "Voltar ao sistema"}; public OptionDialog() { setSize(400, 300); setTitle("Exemplo de Dialogo"); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); int selecionado = JOptionPane.showOptionDialog(getContentPane(), "Existem registros no salvos.", "Sair", 39

Acesso a Banco de Dados JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]); } public static void main(String args[]) { OptionDialog app = new OptionDialog(); } } Cldigo 4-14: Utilizao de JOptionDialog().

A chamada ao mtodo showOptionDialog(), possui uma sintaxe um pouco diferente das estudadas anteriormente. Esta chamada pode ser realizada de duas formas, a primeira delas definindo quais sero os botes a exibir atravs do parmetro JOptionPane.YES_NO_OPTION, utilizando um dos disponveis na tabela abaixo: YES_NO_OPTION YES_NO_CANCEL_OPTION Exibe um dois botes com nome Sim e No conforme configurao do Look And Feel da plataforma local. Exibe um trs botes com nome Sim, No e Cancelar conforme configurao do Look And Feel da plataforma local. Exibe um dois botes com nome Ok e Cancelar conforme configurao do Look And Feel da plataforma local.

OK_CANCEL_OPTION

Tabela 4-5: Conjuntos de botes pr-configurados para JOptionPane.

A segunda forma como o programa acima realiza, utilizando os dois ltimos parmetros deste mtodo para informar no primeiro um vetor com o nome dos botes e no segundo o nome do boto padro.

40

Acesso a Banco de Dados

JTable
A classe JTable utilizada para exibir tabelas de dados e caso necessrio permitir que o usurio manipule estes dados. Para maior compreenso segue o exemplo de criao de uma tabela simples:

Figura 4-15: Criando uma JTable simples

package com.targettrust.java.capitulo04; import java.awt.*; import javax.swing.*; public class Tabelas extends JFrame { public Tabelas() { getContentPane().setLayout(new GridLayout(1,0)); setTitle("Exemplo de tabelas"); Object[] nomeColunas = {"CDIGO", "FRUTA", "COR"}; Object[][] dados = { {new Integer(1), {new Integer(2), {new Integer(3), }; "Maa", "Vermelho"}, "Banana", "Amarelo"}, "Limo", "Verde"}

JTable tabela = new JTable(dados, nomeColunas); tabela.setSize(200, 50); JScrollPane scrollPane = new JScrollPane(tabela); getContentPane().add(scrollPane); setSize(400, 300); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); } public static void main(String args[]) { Tabelas app = new Tabelas(); } } Cdigo 4-15: Exemplo de JTable simples.

41

Acesso a Banco de Dados

Observando o programa exemplo a primeira tarefa a ser realizada a montagem da origem dos dados. O programa declara uma matriz de Object[][] e inicializa a mesma com o contedo da JTable. Alm disto cria um vetor Object[] contendo os nomes das colunas. Montada a origem dos dados, criado o objeto JTable que recebe como parmetros os dados obtidos nas linhas anteriores (o vetor e a matriz). Em seguida definido o tamanho da tabela. Aps a tabela montada, o programa define um JScrollPane, adiciona a tabela a ele e por fim adiciona o JScrollPane ao layout. O JScrollPane automaticamente ir exibir o nome das colunas no cabealho e controlar os scrolls. Caso deseje utilizar uma JTable sem o JScrollPane, o cabealho pode ser definido atravs da classe JTableHeader, consulte a API SDK para maiores informaes.

Alterando a largura de uma coluna: Para modificar a largura de visualizao de uma coluna, necessrio utilizar o seguinte cdigo:
tabela.getColumnModel().getColumn(1).setPreferredWidth(5); Cdigo 4-16: Alterando a largura de visualizao de uma coluna.

No exemplo acima verifica-se que o mtodo getColumn() recebe como parametro um inteiro. Este inteiro o nmero da coluna ou a posio no vetor (iniciando em zero) que possue o nome das colunas.

Utilizando o auto re-dimensionamento de colunas: A classe JTable atravs do mtodo setAutoResizeMode() permite que colunas sejam redimensionadas automaticamente quando so manipuladas conforme o exemplo abaixo:
tabela.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); Cdigo 4-17: Ajustando automaticamente a largura das colunas.

No exemplo acima verifica-se que o mtodo setAutoResizeMode() recebe como parametro uma constante que a propriedade que dita a forma com a qual vai ser feito o redimensionamento. Segue abaixo uma tabela com as constantes disponveis e suas funes:

42

Acesso a Banco de Dados

AUTO_RESIZE_SUBSEQUENT_COLU MNS AUTO_RESIZE_NEXT_COLUMN AUTO_RESIZE_ALL_COLUMNS AUTO_RESIZE_OFF

a forma padro de redimensionamento. Ajusta todas as colunas posteriores a coluna modificada. Ajusta somente as colunas imediatamente a esquerda ou a direita da coluna modificada. Redimensiona todas as colunas da tabela. Desliga o redimensionamento automtico de colunas.

Tabela 4-6: Modos de redimensionamento automtico de colunas em uma JTable.

43

Acesso a Banco de Dados

JScrollPane
JScrollPane fornece uma viso com scroll de um componente da GUI. Normalmente utilizado quando o tamanho de uma tela menor que a quantidade de informaes que se deseja mostrar. Em outras palavras JScrollPane responsvel pela exibio de barras de rolagem. O cdigo para impelentao de um JScrollPane extremamente simples veja o exemplo abaixo:

Figura 4-17: Exemplo de JScrollPane.

package com.targettrust.java.capitulo04; import java.awt.*; import javax.swing.*; public class ExemploScroll extends JFrame { private JTextArea jTextArea1 = new JTextArea(); private Container c; public ExemploScroll() { c = getContentPane(); getContentPane().setLayout(new BorderLayout()); setTitle("Exemplo de JScrollPane"); jTextArea1.setBounds(new Rectangle(70, 45, 210, 140)); JScrollPane scroll = new JScrollPane(jTextArea1); getContentPane().add(scroll, BorderLayout.CENTER); setDefaultCloseOperation(EXIT_ON_CLOSE); setSize(400, 300); setVisible(true);

public static void main(String args[]) { ExemploScroll app = new ExemploScroll(); } } Cdigo 4-18: Exemplo de utilizao de JScrollPane 44

Acesso a Banco de Dados

No programa exemplo utilizado, declarada uma JTextArea, logo em seguida instanciado um objeto de JScrollPane recebendo como parmetro a JTextArea e por fim o scroll que possui a caixa de texto associado ao layout. Note bem que a caixa de texto no foi adicionada ao layout, mas sim ao scroll e este por sua vez adicionado. Ou seja, a utilizao de JScrollPane extremamente simples, instencia-se um novo objeto passando-se a ele o objeto de destino a ser adicionado o scrol e por fim este adicionado ao layout. O JScrollPane permite que sejam criadas regras para exibio ou no das barras de rolagem, estas regras so definidas atravs dos seguintes mtodos que recebem os parmetros (constantes) indicados nas tabelas seguintes:

setHorizontalScrollBarPolicy HORIZONTAL_SCROLLBAR_AS_NEED ED HORIZONTAL_SCROLLBAR_ALWAYS HORIZONTAL_SCROLLBAR_NEVER

Barra de rolagem exibida somente quando necessrio. Barra de rolagem exibida independente da necessidade. Barra de rolagem nunca exibida.

Tabela 4-7: Regras para exibio de bara de rolagem horizontal

setVerticalScrollBarPolicy VERTICAL_SCROLLBAR_AS_NEEDED VERTICAL_SCROLLBAR_ALWAYS VERTICAL_SCROLLBAR_NEVER

Barra de rolagem exibida somente quando necessrio. Barra de rolagem exibida independente da necessidade. Barra de rolagem nunca exibida.

Tabela 4-8: Regras para exibio de bara de rolagem vertical

45

Acesso a Banco de Dados

JFileChooser
JFileChooser exibe uma GUI para navegar pelo sistema de arquivos escolher arquivos ou diretrios, a conhecida janela para seleo de arquivo (Ex: Abrir..., Salvar..., etc.). O Look And Feel ir determinar o que ser exibido de opes nestas caixas de dilogo.

Figura 4-18: Exemplo de JFileChooser.

package com.targettrust.java.capitulo04; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Arquivo extends JFrame { private JFileChooser file = new JFileChooser(); private Container c; public Arquivo() { c = getContentPane(); c.setLayout(null); setTitle("Exemplo de JFileChooser"); JButton botao = new JButton("Selecionar Arquivo"); botao.setSize(100, 30); c.add(botao); botao.addActionListener( new ActionListener() { 46

Acesso a Banco de Dados public void actionPerformed(ActionEvent e ) { if (file.showOpenDialog(getContentPane()) == JFileChooser.APPROVE_OPTION) { JOptionPane.showMessageDialog(getContentPane(), file.getSelectedFile().getName()); } else { JOptionPane.showMessageDialog(getContentPane(), "Operao cancelada"); } } } ); setSize(400, 300); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true);

public static void main(String args[]) { Arquivo app = new Arquivo(); } } Cdigo: 4-19: Exemplo de utilizao de JFileChooser.

No programa acima, criado um boto (JButton) chamado Selecionar Arquivo, ao clicar em selecionar arquivo exibida uma janela de escolha de arquivos no sistema de arquivos. Para exibir esta janela utilizado o mtodo showOpenDialog() a classe JFileChooser. Este mtodo retorna um inteiro com o boto clicado pelo usurio na janela de selo de arquivos. Este inteiro testado e caso refira-se a um OK, exibe o nome do arquivo selecionado, caso contrrio exibe um alerta de operao cancelada. Para permitir que o usurio selecione apenas diretrios e no arquivos pode-se utilizar o mtodo:
file.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); Cdigo 4-20: Exemplo de seleo de diretrios com JFileChooser.

Para maiores informaes consulte a API SDK sobre JFileChooser.

47

Acesso a Banco de Dados

Exerccios
Neste captulo voc conheceu os componentes grficos mais comuns para criao de interfaces grficas. Agora voc ir praticar alguns destes componentes em um exerccio. 1. Crie uma interface grfica como mostrado na figura abaixo:

48

Acesso a Banco de Dados

Espao para anotaes

49

5. Look And Feel

Acesso a Banco de Dados

Objetivos
Conhecer o funcionamento do Look And Feel Aplicar o recurso de Look And Feel na aplicao

Acesso a Banco de Dados

Aparncia e Comportamento

Um programa que utiliza componentes GUI do Abstract Windowing Toolkit de Java (pacote java.awt) assume a aparncia e comportamento da plataforma em que o programa executa. Um programa Java executando em um Macintosh se parece com outros programas que executam em um Macintosh. Um programa Java executando no Microsoft Windows se parece com outros programas que executam no Microsoft Windows. Um programa Java que executa em uma plataforma UNIX se parece outros programas que executam nessa plataforma UNIX. Isso pode ser desejvel, uma vez que permite aos usurios do programa em cada plataforma utilizar os componentes GUI com que eles j esto familiarizados. Entretanto, isso tambm introduz questes interessantes de portabilidade. Componentes GUI do Swing de peso leve eliminam muitas dessas questes fornecendo funcionalidade uniforme de uma plataforma para outra e definindo aparncia e comportamento uniformes para diversas plataformas conhecida como aparncia de metal - metal look-and-feel). O Swing tambm fornece a flexibilidade para personalizar a aparncia e comportamento com o estilo do Microsoft Windows ou com o estilo do Motif (UNIX). O exemplo abaixo demonstra como alterar a aparncia e comportamento de uma GUI do Swing. O programa cria vrios componentes GUI para permitir ver a alterao na aparncia e comportamento de vrios componentes GUI ao mesmo tempo. A primeira janela da sada mostra a aparncia padro de metal, a segunda janela de sada mostra a aparncia e comportamento do Motif e a terceira janela de sada mostra a aparncia e comportamento do Windows.
package com.target.swing.capitulo05; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class LookAndFeelDemo extends JFrame { private String strings[] = { "Metal", "Motif", "Windows" }; private UIManager.LookAndFeelInfo[] looks = UIManager.getInstalledLookAndFeels(); private JRadioButton[] radio; 3

Acesso a Banco de Dados private private private private ButtonGroup group; JButton button; JLabel label; JComboBox comboBox;

private class ItemHandler implements ItemListener { public void itemStateChanged( ItemEvent e ) { // varre os itens para ver qual foi selecionado for ( int i = 0; i < radio.length; i++ ) if ( radio[ i ].isSelected() ) { label.setText( "This is a " + strings[ i ] + " look-and-feel" ); comboBox.setSelectedIndex( i ); change( i ); } } } public LookAndFeelDemo() { super( "Look and Feel Demo" ); Container c = getContentPane(); JPanel northPanel = new JPanel(); northPanel.setLayout( new GridLayout( 3, 1, 0, 5 ) ); label = new JLabel( "This is a Metal look-and-feel", SwingConstants.CENTER ); northPanel.add( label ); button = new JButton( "JButton" ); northPanel.add( button ); comboBox = new JComboBox( strings ); northPanel.add( comboBox ); c.add( northPanel, BorderLayout.NORTH ); JPanel southPanel = new JPanel(); radio = new JRadioButton[ strings.length ]; group = new ButtonGroup(); LookAndFeelDemo.ItemHandler handler = new LookAndFeelDemo.ItemHandler(); southPanel.setLayout( new GridLayout( 1, radio.length ) ); for ( int i = 0; i < radio.length; i++ ) { radio[ i ] = new JRadioButton( strings[ i ] ); radio[ i ].addItemListener( handler ); group.add( radio[ i ] ); southPanel.add( radio[ i ] ); } c.add( southPanel, BorderLayout.SOUTH ); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize( 300, 200 ); setVisible(true); 4

Acesso a Banco de Dados radio[ 0 ].setSelected( true ); } private void change( int value ) { try { UIManager.setLookAndFeel( looks[ value ].getClassName() ); SwingUtilities.updateComponentTreeUI( this ); } catch ( Exception e ) { e.printStackTrace(); } } public static void main( String args[] ) { LookAndFeelDemo dx = new LookAndFeelDemo(); } } Cdigo 5-1: Exemplo de utilizao de Look And Feel

O programa acima define o Look And Feel a ser utilizado atravs de programao. Alm desta forma, o Look And Feel pode ser definido de outras duas maneiras conforme segue: Definindo o Look And Feel atravs de linha de comando: Definindo o Look And Feel por linha de comando possvel deixar a aplicao configurvel para que possa ter sua aparnciia e comportamento modificado sem necessidade de alterao de programa ou configurao. A execuo da aplicao deve seguir o exemplo abaixo:
java -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel MyApp Cdigo 5-2: Exemplo de configurao do Look And Feel atravs da linha de comando.

Definindo o Look And Feel atravs do arquivo swing.properties: Outra maneira de determinar o Look And Feel de uma aplicao Swing atravs do arquivo de configurao swing.properties. Este arquivo esta localizado no diretrio lib do distribuio Java. Dentro do arquivo, o Look And Feel definido na seguinte linha:
# Swing properties swing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel

Acesso a Banco de Dados

Exerccios
1. Para a aplicao montada anteriormente adicione o recurso de troca de aparncia grfica ao item de menu Look And Feel 2. Antes da criao do JFrame na interface da sua aplicao insira a seguinte linha de comando para que a aparncia do JFrame seja alterada. JFrame.setDefaultLookAndFeelDecorated(true);

Acesso a Banco de Dados

Espao para anotaes

Acesso a Banco de Dados

6. Arquivos

Acesso a Banco de Dados

Objetivos
Apresentar os fluxos de dados: InputStream OutputStream Conhecer classes que permitam: Serializar objetos Gravar arquivos texto Verificar como funciona o coletor de lixo Implementar estes recursos na aplicao do curso

Acesso a Banco de Dados

Introduo
O armazenamento de dados em variveis e arrays temporrio os dados so perdidos quando uma varivel local sai do escopo ou quando o programa terminar. Arquivos so utilizados para reteno a longo prazo de grandes quantidades de dados, mesmo depois de terminar o programa que criou os dados. Os dados mantidos em arquivos so freqentemente chamados de dados persistentes. Os computadores armazenam arquivos em dispositivos de armazenamento secundrios como discos magnticos, discos pticos e fitas magnticas. Neste captulo, veremos como arquivos de dados so criados, atualizados e processados por programas Java. O processamento de fluxos um assunto extenso. O processamento de arquivos um dos recursos mais importantes que uma linguagem deve ter para suportar aplicativos comerciais que, em geral, processam quantidades macias de dados persistentes. Neste capitulo, discutire-mos os poderosos e abundantes recursos de processamento de arquivos e de fluxos de entrada/sada de Java.

Acesso a Banco de Dados

Hierarquia de Dados
Em ltima instncia, todos os itens de dados processados por um computador so reduzidos a combinaes de zeros e uns. Isso ocorre porque simples e econmico construir dispositivos eletrnicos que podem assumir dois estados estveis um estado representa 0 e o outro estado representa 1. notvel que as impressionantes funes realizadas pelos computadores envolvam somente as manipulaes mais fundamentais de 0s e 1s. O menor item de dados em um computador pode assumir o valor 0 ou o valor 1. Esse item de dados chamado de bit (abreviao de binary digit um dgito que pode assumir um de dois valores). Os circuitos de computador realizam vrias manipulaes de bits simples, tais como examinar o valor de um bit, configurar o valor de um bit e inverter um bit (de 1 para 0 ou de 0 para 1). incmodo para programadores trabalhar com dados na forma de baixo nvel de bits. Em vez disso, os programadores preferem trabalhar com dados em formas como dgitos decimais (isto , 0, 1, 2, 3, 4, 5, 6, 7, 8 e 9),letras (por exemplo, A a Z e a a z) e smbolos especiais (isto , $, @, %, &, ~, (,), -, +, ~, :,?, 1 e muitos outros). Os dgitos, as letras e os smbolos especiais so referidos como caracteres. O conjunto de todos caracteres utilizado para escrever programas e representar itens de dados em um computador particular chamado de o conjunto de caracteres desse computador. Como os computadores podem processar somente 1s e 0s, cada caractere em um conjunto de caracteres do computador representado como um padro de 1s e 0s (caracteres em Java so caracteres unicode compostos de 2 bytes). Os bytes so mais comumente compostos de oito bits. Os programadores criam programas e dados com caracteres; os computadores manipulam e processam esses caracteres como padres de bits. Assim como os caracteres so compostos de bits, os campos so compostos de caracteres. Um campo um grupo de caracteres que possui um significado. Por exemplo, um campo consistindo em letras minsculas e maisculas pode ser utilizado para representar um nome de pessoa. Os dados processados por computadores formam uma hierarquia de dados em que itens de dados tomam-se maiores e mais complexos em termos de estrutura medida que progredimos de bits, para caracteres, para campos; etc.
4

Acesso a Banco de Dados

Um registro (isto , uma class em Java) geralmente composto de vrios campos (chamados de variveis de instncia em Java). Em um sistema de folha de pagamento, por exemplo, um registro para um empregado particular talvez consista nos seguintes campos: Nmero de identificao do empregado Nome Endereo Salrio-hora Nmero de isenes reivindicadas Lucros no ano at a data atual Total de impostos retidos Portanto, um registro um grupo de campos relacionados. No exemplo, cada um dos campos pertence ao mesmo empregado. Naturalmente, uma empresa particular pode ter muitos empregados e ter um registro de folha de pagamento para cada empregado. Um arquivo um grupo de registros relacionados. O arquivo de folha de pagamento de uma empresa normalmente contm um registro para cada empregado. Portanto, um arquivo de folha de pagamento de uma empresa pequena talvez contenha apenas 22 registros, enquanto um arquivo de folha de pagamento de uma empresa grande talvez contenha 100.000 registros. No incomum uma empresa ter muitos arquivos, que contm alguns milhes, ou mesmo bilhes, de caracteres de informaes. Para facilitar a recuperao de registros especficos de um arquivo, pelo menos um campo em cada registro escolhido como uma chave de registro. Uma chave de registro identifica um registro como pertencente a uma parti-cular pessoa ou entidade que nica dentre todos os outros registros. No registro de folha de pagamento descrito anteriormente, o nmero de identificao do empregado normalmente seria escolhido como a chave de registro. H muitas maneiras de organizar registros em um arquivo. O tipo de organizao mais comum chamado de arquivo seqencial, no qual os registros so geralmente armazenados em ordem pelo campo-chave de registro. Em um arquivo de folha de pagamento, os registros normalmente so ordenados pelo nmero de identificao do empregado.
5

Acesso a Banco de Dados

O primeiro registro de empregado no arquivo contm o nmero mais baixo de identificao de empregado e os registros subseqentes contm nmeros de identificao de empregado cada vez mais altos. A maioria das empresas utiliza muitos arquivos diferentes para armazenar dados. Por exemplo, empresas podem ter arquivos de folha de pagamento, arquivos de contas a receber (listagem de valores devidos por clientes), arquivo de contas a pagar (listagem de valores devidos a fornecedores), arquivo de inventrio (listagem de fatos sobre todos os itens abrangidos pelo negcio) e muitos outros tipos de arquivo. Um grupo de arquivos relacionados s vezes chamado de banco de dados. Uma coleo de programas projetados para criar e gerenciar bancos de dados chamada de sistema de gerenciamento de bancos de dados (database management system - DBMS).

Acesso a Banco de Dados

Arquivos e Fluxos
Java v cada arquivo como um fluxo seqencial de bytes. Cada arquivo acaba com um marcador de fim do arquivo ou em um nmero especfico de byte registrado em uma estrutura administrativa de dados mantida pelo sistema. Quando um arquivo aberto, um objeto criado e um fluxo associado com o objeto. Trs objetos de fluxo so criados para ns automaticamente quando iniciamos a execuo de um programa Java System.in, System.out e System.err. Os fluxos associados com esses objetos fornecem canais de comunicao entre um programa e um arquivo ou dispositivo particular. Por exemplo, o objeto System.in (objeto de fluxo de entrada padro) permite que um programa insira bytes via teclado, o objeto System.out (objeto de fluxo de sada padro) permite a um programa dar sada a dados na tela e o objeto System.err (objeto defluxo de erro padro) permite a um programa dar sada a mensagens de erro na tela. Cada um desses fluxos pode ser redireciona-do por exemplo, System.out pode ser redirecionado para enviar sua sada para um arquivo em disco. Para realizar processamento de arquivos em Java, o pacote java.io deve ser importado. Esse pacote inclui definies para as classes de fluxo como FilelnputStream (para entrada de um arquivo) e FileOutputStream (para sada para um arquivo). Os arquivos so abertos criando-se objetos dessas classes de fluxo que herdam das classes InputStream e OutputStream, respectivamente. Portanto, os mtodos dessas classes de fluxo tambm podem ser aplicados a fluxos de arquivo. Para realizar entrada e sada de tipos de dados, os objetos de classe ObjectlnputStream, DatalnputStream, ObjectQutputStream e DataOutputStream sero utilizados junto com as classes de fluxo de arquivo. Os relacionamentos de herana de muitas das classes de E/S de Java esto resumidos no polgrafo. Java oferece muitas classes para realizar entrada/sada. Fornecemos uma breve viso geral de cada uma e como elas se relacionam entre si. Colocamos vrias classes de fluxo chave para trabalhar medida que implementamos uma variedade de programas de processamento de arquivos que criam, manipulam e destroem arquivos de acesso seqencial. InputStream (uma subclasse de Object) e OutputStream (uma subclasse de Object) so classes abstract que definem mtodos para realizar entrada e sada respectivamente; suas classes derivadas sobrescrevem esses mtodos.

Acesso a Banco de Dados

A entrada/sada de arquivos feita com FilelnputStream (uma subclasse de InputStream) e FileOutputStream (uma subclasse de OutputStream). Os pipes so canais de comunicao sincronizados entre threads. Um pipe estabelecido entre dois threads. Um thread envia dados para outro gravando em uma PipedOutputStream (uma subclasse de OutputStream). A thread de destino l as informaes do pipe via um PipedInputStream (uma subclasse de InputStream).

Parte da hierarquia de classes do pacote java.io: java.lang.Object File FileDescriptor InputStream ByteArraylnputStream FilelnputStream FilterlnputStream BufferedlnputStream DatalnputStream PushbacklnputStream ObjectlnputStream PipedlnputStream SequencelnputStream OutputStream ByteArrayOutputStream FileOutputStream FilterOutputStream BufferedOutputStream DataOutputStream PushbackOutputStream ObjectOutputStream PipedOutputStream

Uma PrintStream (uma subclasse de FilterOutputStream) utilizada para enviar a sada para a tela (ou a sada-padro como definido por seu sistema operacional local). Na verdade, temos utilizado a sada PrintStream por todo o texto at este ponto; System.out um PrintStream (assim como System.err). Um FilterlnputStream filtra um InputStream e um FilterOutStream filtra um OutputStream; filtrar significa simplesmente que o fluxo de filtro fornece funcionalidade adicional como armazenamento em buffer, monitoramento de nmeros de linha ou agregao de bytes de dados em unidades que formam um tipo de dados primitivo.
8

Acesso a Banco de Dados

Ler dados diretamente como bytes rpido mas grosseiro. Normalmente os programas lem dados como agregados de bytes que formam um int, um float, um double e assim por diante. A interface DataInput implementada pela classe DataInputStream (discutidas mais adiante neste captulo), a qual precisa ler tipos de dados primitivos de um fluxo. DataInputStreams permitem a um programa ler dados binrios de um InputStream. A interface DataInput inclui mtodos read (para os arrays de byte), readBoolean, readByte, readChar, readDouble, readFloat, readFully (para arrays de byte), readInt, readLong, readShort, readUnsignedByte, readUnsignedShort, readUTF (para Strings) e skipBytes. A interface DataOutput implementada pela classe DataOutputStream (uma subclasse de FilterOutputStream), a qual precisa gravar tipos de dados primitivos em um OutputStream. DataOutputStreams permitem a um programa gravar dados binrios em um OutputStream. A interface DataOutput inclui mtodos flush, size, write (para um byte), write (para um array de byte), writeBoolean, writeByte, writeBytes, writeChar, writeChars (para Strings Unicode), writeDouble, writeFloat, writeInt, writeLong, writeShort e writeUTF. O armazenamento em buffer (buffering) uma tcnica de aprimoramento do desempenho de EIS. Com um BufferedOutputStream (uma subclasse de classe FilterOutputStream), cada instruo de sada no resulta necessariamente em uma transferncia fisica real de dados para o dispositivo de sada. Em vez disso, cada operao de sada dirigida para uma regio na memria, chamada buffe;; que suficientemente grande para armazenar os dados de muitas operaes de sada. Ento a transferncia real para o dispositivo de sada realizada em uma grande operao fsica de sada toda vez que o buffer se enche. As operaes de sada dirigidas para o buffer de sada na memria so freqentemente chamadas de operaes lgicas de sada. Com um BufferedInputStream (uma subclasse de classe FilterInputStream), muitos pedaos ou trechos lgicos de dados de um arquivo so lidos como uma grande operao fsica de entrada em um buffer de memria. A medida que o programa solicita cada novo trecho dos dados, feita uma busca no buffer (isso s vezes referido como uma operao lgica de entrada). Quando o buffer est vazio, a operao fsica de entrada do dispositivo de entrada realizada lendo (read in) o prximo grupo de trechos lgicos de dados. Portanto, o nmero de operaes fsicas reais de entrada pequeno comparado com o nmero de solicitaes de leitura emitido pelo programa.
9

Acesso a Banco de Dados

Com um BufferedOutputStream, um buffer parcialmente preenchido pode ser forado a dar sada no dispositivo a qualquer momento com um flush explcito como segue:

testBufferedoutputStream.flush();

Cdigo 6-1: Descarga do buffer

Uma PushBackInputStream (uma subclasse de classe FilterInputStream) utilizada para aplicaes mais exticas que a maioria dos usurios precisa. Essencialmente, o aplicativo que l um PushBackInputStream l bytes do fluxo e forma agregados consistindo em vrios bytes. As vezes, para determinar que o agregado est completo, o aplicativo deve ler o primeiro caractere alm do fim (past the end) do primeiro agregado. Uma vez que o programa determinou que o agregado atual est completo, o caractere extra reinserido (pushed back) no fluxo. PushBackInputStreams so utilizados por programas como compiladores que analisam sintaticamente (parse) suas entradas, isto , eles as dividem em unidades significativas (como palavras-chave, identificadores e operadores que o compilador Java deve reconhecer). Quando variveis de instncia de objetos so enviadas para a sada em um arquivo de disco, em certo sentido perdemos as informaes do tipo do objeto. Em um disco, temos apenas dados, no as informaes de tipo. Se o programa que ler esses dados conhece o tipo de objeto a que eles correspondem, ento esses dados so simplesmen-te lidos para objetos desse tipo. As vezes, queremos ler ou gravar um objeto inteiro em um arquivo. As classes ObjectInputStreams e ObjectoutputStream, que implementam respectivamente as interfaces ObjectInput e ObjectOutput, so utilizadas para esse propsito. Freqentemente encadeamos ObjectInputStreams com FileInputStreams (Tambm encadeamos ObjectOutputStreams com FileOutputStreams). A interface ObjectOutput tem um writeObject que aceita um Object como um argumento e grava suas informaes na OutputStream. Correspondentemente, a interface ObjectInput requer o mtodo readObject, que l e retorna um Object de um InputStream. Esse objeto, ento, pode sofrer coero para o tipo desejado. Alm disso, essas interfaces incluem outros mtodos centrados em Object, bem como os mesmos mtodos que DataInput e DataOutput para leitura e gravao de tipos de dados primitivos.

10

Acesso a Banco de Dados

O fluxo de E/S de Java inclui capacidades para entrada de arras de byte na memria e sada de arrays de byte na memria. Um ByteArrayInputStream (uma subclasse da classe abstract InputStream) realiza suas entradas a partir de um array de byte na memria. Um ByteArrayOutputStream (uma subclasse da classe abstractOutputStream) coloca a sada em um array de byte na memria. Uma aplicao da E/S de array de byte a validao de dados. Um programa pode inserir uma linha inteira por vez do fluxo de entrada em um array de byte. Ento uma rotina de validao pode escrutinar o contedo do array de byte e corrigir os dados, se necessrio. O programa agora pode continuar a entrada a partir do array de byte, sabendo que os dados de entrada esto no formato adequado. Dar sada para um array de byte uma boa maneira de tirar proveito das poderosas capacidades de formatao de fluxos de sada de Java. Os dados podem ser preparados em um array de byte para simular o formato editado de tela. Esse array, ento, grava em um arquivo de disco para preservar a imagem de tela. Uma SequenceInputStream (uma subclasse da classe abstractInputStream) permite que vrios InputStreams sejam concatenados de modo que o programa veja o grupo como um nico InputStream. medida que o fim de cada fluxo de entrada alcanado, o fluxo fechado e o prximo fluxo na seqncia aberto. A classe BufferedReader (uma subclasse da classe abstract Reader) e a classe BufferedWriter (uma subclasse da classe abstract Writer) permitem eficiente armazenamento em buffer para fluxos baseados em caracteres. Fluxos baseados em caracteres utilizam caracteres Unicode esses fluxos podem processar dados em qualquer linguagem que seja representada pelo conjunto de caracteres Unicode. A classe CharArrayReader e a classe CharArrayWriter lem e gravam um fluxo de caracteres em um array de caracteres. Uma PushbackReader (uma subclasse da classe abstract FilterReader) permite que caracteres sejam colocados de volta em um fluxo de caracteres. Uma LineNumberReader (uma subclasse de BufferedReader) fornece um fluxo buferizado de caracteres que monitora nmeros de linha (isto , uma nova linha, um retorno de carro ou uma combinao de quebra de linha e de retorno de carro). As classes FileReader (uma subclasse de InputStreamReader) e FileWriter (uma subclasse de OutputStreamWriter) lem e gravam caracteres em um arquivo.

11

Acesso a Banco de Dados

As classes PipedReader e PipedWriter fornecem fluxos de caracteres colocados em pipe. As classes StringReader e StringWriter lem e gravam caracteres em Strings. Uma PrintWriter grava caracteres em um fluxo. A classe File permite que os programas obtenham informaes sobre um arquivo ou diretrio.

12

Acesso a Banco de Dados

Testando Arquivos
A aplicao posterior responsvel por realizar o teste em um File verificando se o usurio est tentando abrir um arquivo ou diretrio a partir do JTextField especificado na tela. Caso o usurio informe um path de um arquivo o programa efetua a listagem dele, informando as principais caractersticas de um arquivo qualquer.

package com.targettrust.java.capitulo06; import import import import java.awt.*; java.awt.event.*; java.io.*; javax.swing.*;

public class FileTest extends JFrame implements ActionListener { private JTextField enter; private JTextArea output; public FileTest() { super( "Testando a classe File" ); enter = new JTextField("Digite o caminho do arquivo ou diretrio:" ); enter.addActionListener( this ); output = new JTextArea(); Container c = getContentPane(); ScrollPane p = new ScrollPane(); p.add( output ); c.add( enter, BorderLayout.NORTH ); c.add( p, BorderLayout.CENTER ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setSize( 400, 400 ); setVisible(true);

public void actionPerformed( ActionEvent e ) { File name = new File( e.getActionCommand() ); // Se existe o arquivo if ( name.exists() ) { output.setText( name.getName() + " existe\n" + ( name.isFile() ? " um arquivo\n" : " um arquivo\n" ) + ( name.isDirectory() ? "is a directory\n" : " um diretrio\n") + ( name.isAbsolute() ? "is absolute path\n" : "no um caminho absoluto\n" ) + "\nltima modificao: " + name.lastModified() + "\nTamanho: " + name.length() + "\nCaminho: " + name.getPath() + "\nCaminho absoluto: " + name.getAbsolutePath() + 13

Acesso a Banco de Dados "\nDiretrio pai: " + name.getParent() ); if ( name.isFile() ) { try { RandomAccessFile r = new RandomAccessFile( name, "r" ); StringBuffer buf = new StringBuffer(); String text; output.append( "\n\n" ); while( ( text = r.readLine() ) != null ) { buf.append( text + "\n" ); } output.append( buf.toString() ); } catch( IOException e2 ) { JOptionPane.showMessageDialog( this, "FILE ERROR", "FILE ERROR", JOptionPane.ERROR_MESSAGE ); } } else if ( name.isDirectory() ) { String directory[] = name.list(); output.append( "\n\nContedo do diretrio:\n"); for ( int i = 0; i < directory.length; i++ ) output.append( directory[ i ] + "\n" ); }

} else { JOptionPane.showMessageDialog(this, e.getActionCommand()+ " No existe","FILE ERROR",JOptionPane.ERROR_MESSAGE); } } public static void main( String args[] ) { FileTest app = new FileTest(); } } Cdigo 6-2: Testando a classe File

Caso o usurio digitar um path de diretrio ser realizado uma listagem de arquivo e subdiretrios pertencentes ao diretrio corrente.

14

Acesso a Banco de Dados

Figura 6-1: Classe FileTest rodando

15

Acesso a Banco de Dados

Criando um Arquivo
Java no impe nenhuma estrutura a um arquivo. Logo, noes como registro no existem em arquivos Java. Portanto, o programador deve estruturar arquivos para atender aos requisitos de aplicativos. No exemplo a seguir, vemos como o programador impe uma estrutura simples de registro a um arquivo. O exemplo cria um arquivo de acesso seqencial simples que poderia ser utilizado em um sistema de contas a receber para ajudar a gerenciar o valor devido por um cliente da empresa. Para cada cliente, o programa obtm um nmero de conta, o primeiro nome, o sobrenome e o saldo do cliente (isto , a quantia que o cliente ainda deve empresa pelas mercadorias e servios recebidos no passado). Os dados obtidos para cada cliente constituem um registro desse cliente. O nmero da conta utilizado como chave de registro nesse aplicativo; isto , o arquivo ser criado e mantido ordenado pelo nmero de conta. Esse programa assume que o usurio insere os registros em ordem de nmero de conta. Em um sistema abrangente de contas a receber, um recurso de classificao fornecido para o usurio poder inserir o registro em qualquer ordem os registros ento seriam classificados e gravados no arquivo.
package com.targettrust.java.capitulo06; import import import import java.awt.*; java.awt.event.*; javax.swing.*; java.io.*;

public class BankUI extends JPanel { protected final static String names[] = {"Account number", "First name", "Last name", "Balance" }; protected JLabel labels[]; protected JTextField fields[]; protected JButton doTask, doTask2; protected JPanel innerPanelCenter, innerPanelSouth; protected int size = 4; public BankUI() { this( 4 ); } public BankUI( int mySize ) { size = mySize; 16

Acesso a Banco de Dados labels = new JLabel[ size ]; fields = new JTextField[ size ]; for ( int i = 0; i < labels.length; i++ ) { labels[ i ] = new JLabel( names[ i ] ); } for ( int i = 0; i < fields.length; i++ ) { fields[ i ] = new JTextField(); } innerPanelCenter = new JPanel(); innerPanelCenter.setLayout( new GridLayout( size, 2 ) ); for ( int i = 0; i < size; i++ ) { innerPanelCenter.add( labels[ i ] ); innerPanelCenter.add( fields[ i ] ); } doTask = new JButton(); doTask2 = new JButton(); innerPanelSouth = new JPanel(); innerPanelSouth.add( doTask2 ); innerPanelSouth.add( doTask ); setLayout( new BorderLayout() ); add( innerPanelCenter, BorderLayout.CENTER ); add( innerPanelSouth, BorderLayout.SOUTH ); validate(); } public void clearFields() { for ( int i = 0; i < size; i++ ) { fields[ i ].setText( "" ); } } public JButton getDoTask() { return doTask; } public JButton getDoTask2() { return doTask2; } public JTextField[] getFields() { return fields; } public String[] getFieldValues() { String values[] = new String[ size ]; for ( int i = 0; i < size; i++ ) values[ i ] = fields[ i ].getText(); } return values;

17

Acesso a Banco de Dados

public void setFieldValues( String s[] ) throws IllegalArgumentException { if ( s.length != size ) { throw new IllegalArgumentException( "There must be " + size + " Strings in the array" ); } for ( int i = 0; i < size; i++ ) { fields[ i ].setText( s[ i ] ); }

} }

Cdigo 6-3: Cdigo da classe para o painel BankUI

package com.targettrust.java.capitulo06; import import import import java.awt.*; java.awt.event.*; javax.swing.*; java.io.*;

public class BankAccountRecord implements Serializable { private private private private int account; String firstName; String lastName; double balance;

public BankAccountRecord() { this( 0, "", "", 0.0 ); } public BankAccountRecord( int acct, String first, String last, double bal ) { account = acct; setFirstName( first ); setLastName( last ); setBalance( bal ); } public int getAccount() { return account; } public double getBalance() { 18

Acesso a Banco de Dados return balance; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public void setAccount( int acct ) { account = acct; } public void setBalance( double bal ) { balance = bal; } public void setFirstName( String first ) { firstName = first; } public void setLastName( String last ) { lastName = last; }

Cdigo 6-4: Classe para representar um registro de conta package com.targettrust.java.capitulo06; import import import import java.awt.*; java.awt.event.*; javax.swing.*; java.io.*;

public class CreateFile extends JFrame { private ObjectOutputStream output; private BankUI userInterface; private JButton enter, open; public CreateFile() { super( "Creating a Sequential File of Objects" ); getContentPane().setLayout( new BorderLayout() ); userInterface = new BankUI(); enter = userInterface.getDoTask(); enter.setText( "Enter" ); enter.setEnabled( false ); enter.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { addRecord(); } }); addWindowListener( 19

Acesso a Banco de Dados new WindowAdapter() { public void windowClosing( WindowEvent e ) { if(output != null) { addRecord(); closeFile(); } System.exit( 0 ); } }); open = userInterface.getDoTask2(); open.setText( "Save As" ); open.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { openFile(); } }); getContentPane().add( userInterface, BorderLayout.CENTER ); setSize( 300, 200 ); show(); } public void addRecord() { int accountNumber = 0; BankAccountRecord record; String fieldValues[] = userInterface.getFieldValues(); // Codigo no nulo if ( ! fieldValues[ 0 ].equals( "" ) ) { try { accountNumber = Integer.parseInt( fieldValues[ 0 ] ); if ( accountNumber > 0 ) { record = new BankAccountRecord( accountNumber, fieldValues[ 1 ], fieldValues[ 2 ], Double.parseDouble( fieldValues[ 3 ] ) ); output.writeObject( record ); output.flush(); } userInterface.clearFields(); } catch ( NumberFormatException nfe ) { JOptionPane.showMessageDialog( this, "Bad account number or balance", "Invalid Number Format", JOptionPane.ERROR_MESSAGE ); } catch ( IOException io ) { closeFile(); } } } private void closeFile() { try { output.close(); } catch( IOException ex ) { JOptionPane.showMessageDialog( this, "Error closing file", "Error", JOptionPane.ERROR_MESSAGE ); System.exit( 1 ); } 20

Acesso a Banco de Dados } public static void main( String args[] ) { new CreateFile(); } private void openFile() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY ); int result = fileChooser.showSaveDialog( this ); if ( result == JFileChooser.CANCEL_OPTION ) { return; } File fileName = fileChooser.getSelectedFile(); if (fileName == null || fileName.getName().trim().equals( "" )){ JOptionPane.showMessageDialog( this, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); } else { try { output = new ObjectOutputStream( new FileOutputStream( fileName ) ); open.setEnabled( false ); enter.setEnabled( true ); } catch ( IOException e ) { JOptionPane.showMessageDialog( this, "Error Opening File", "Error", JOptionPane.ERROR_MESSAGE ); } }

} }

Cdigo 6-5: Janela para gravar um registro

Como a maioria dos programas tem uma GUI semelhante, criamos a classe BankUI para encapsular essa GUI. Tambm criamos a classe BankAccountRecord para encapsular as informaes de registro dos clientes (isto , conta, nome etc.) utilizadas pelos exemplos deste capitulo. A classe BankUI contm dois JButtons e os arrays de JLabels e JTextFields. O nmero de JLabels e JTextFields estabelecido pelo construtor. Tambm fornecido um construtor sem argumentos que passa um valor-padro para o construtor. Os mtodos getFieldValues, setFieldvalues e clearFields so utilizados para manipular o texto dos JTextFields. Os mtodos getFields, getDoTask e
21

Acesso a Banco de Dados

getDoTask2 retornam componentes GUI individuais para que um programa cliente possa adicionar ActionListeners, etc. A classe BankAccountRecord implementa a interface Serializable que permite que objetos BankAccountRecord sejam utilizados com ObjectlnputStreams e ObjectOutputStreams. Essa classe contm os membros de dados private account, firstName, lastName e balance. Essa classe tambm fornece os mtodos public get e set para acessar os membros de dados private. Agora vamos discutir o cdigo que cria o arquivo de acesso seqencial. Nesse exemplo, introduzimos a classe JFileChooser (pacote javax.swing) para selecionar arquivos. Construimos uma instncia de JFileChooser e a atribui referncia fileChooser. Chamamos o mtodo setFileSelectionMode para especificar se arquivos e/ou diretrios podem ser selecionados pelo usurio. Para esse programa, utilizamos a constante static FILES_ONLY de JFileChooser para indicar que somente arquivos podem ser selecionados. Outras constantes static so
int result = fileChooser.showSaveDialog( this );

FILES_AND_DIRECTORIES e DIRECTORIES_ONLY.
Cdigo 6-6: Abertura da janela para escolha de um arquivo

Chamamos o mtodo showSaveDialog para exibir o dilogo de JFileChooser intitulado Save. O argumento this especifica que o dilogo pai de JFileChooser utilizado para determinar a posio do dilogo na tela (se null passado, o dilogo exibido no centro da janela). Quando exibido, um dilogo JFileChooser no permite ao usurio interagir com qualquer outra janela de programa at o dilogo JFileChooser ser fechado (clicando em <Save> ou <Close>). Dilogos que se comportam dessa maneira so chamados de dilogos modais. O usurio seleciona a unidade, o diretrio e o nome do arquivo e clica em <Save>. O mtodo showSaveDialog retorna um inteiro que especifica o boto (<Save> ou <Close>) que foi clicado para fechar o dilogo.

22

Acesso a Banco de Dados

Figura 6-2: Janela para coletar dados da conta

Testamos se <Cancel> foi clicado comparando result com a constante static CANCEL_OPTION. Se foi, o mtodo encerrado.

Figura 6-3: Janela para selecionar um arquivo a ser salvo

O arquivo que o usurio selecionou recuperado chamando o mtodo getSelectedFile. O mtodo getSelectedFile retorna um objeto do tipo File que encapsula as informaes sobre o arquivo (isto , nome, localizao etc.). Esse objeto File no abre o arquivo. Atribumos esse objeto File referncia fileName. Como afirmado anteriormente, arquivos so abertos criando objetos das classes de fluxo FileInputStrean e FileOutputStream. Nesse exemplo, o arquivo ser aberto para sada, ento um objeto FileOutputStream criado com a chamada do construtor.
new FileOutputStrean( fileName )

23

Acesso a Banco de Dados Cdigo 6-7: Criando um canal de sada para um arquivo.

Um argumento passado para o construtor de FileOutputStream um objeto File. Arquivos existentes abertos para sada so truncados - todos os dados no arquivo so descartados. A classe FileOutputStream fornece mtodos para gravar arravs de byte e bytes individuais em um arquivo. Para esse programa, precisamos gravar objetos em um arquivo uma capacidade no fornecida por FileOutputStrean. A soluo para esse problema uma tcnica chamada encadeamento de objetos de fluxo a capacidade de adicionar os servios de um fluxo a outro. Para encadear um ObjectOutputStream com o FileOutputStream, passamos o objeto FileOutputStream para o construtor de ObjectOutputStream.

output = new ObjectOutputStream(new FileOutputStream(fileName));

Cdigo: 6-8: Criando um canal para gravar objetos

Se ocorre uma IOException (uma exceo que disparada quando um arquivo aberto para gravao em uma unidade com espao insuficiente, quando um arquivo de leitura aberto para gravao, quando um arquivo inexistente aberto para leitura, etc.), um JOptionPane exibido. Se a construo dos dois fluxos no disparar uma IOException, o arquivo aberto. A referncia output ento pode ser utilizada para gravar objetos no arquivo. O programa assume que dados foram inseridos corretamente e na ordem adequada de nmero de registro. O usurio preenche os JTextFields e clica em <Enter> para gravar os dados no arquivo. O mtodo actionPerformed do boto <Enter> chama nosso mtodo addRecord para realizar a operao de gravao. O mtodo writeObject chamado para gravar o objeto record nesse arquivo. O mtodo flush chamado para assegurar que quaisquer dados armazenados na memria sejam gravados no arquivo. Quando o usurio clica na caixa de fechamento (o x no canto direito superior da GUI), output testado contra null quanto igualdade. Se o fluxo estiver aberto, os mtodos addRecord e closeFile so chamados. O mtodo closeFile chama o mtodo close para output. Ao utilizar objetos de fluxo encadeados, o objeto mais externo (ObjectOutputStream, nesse exemplo) deve ser utilizado para fechar o arquivo.

24

Acesso a Banco de Dados

Lendo Dados de um Arquivo


Dados so armazenados em arquivos a fim de que possam ser recuperados para processamento quando necessrio. O programa ReadFile l registros de um arquivo criado pelo programa anterior e exibe o contedo dos registros. Os arquivos so abertos para entrada criando-se um objeto FileInputStream. O nome do arquivo aberto passado como um argumento para o construtor FileInputStream. No ltimo exemplo, gravamos objetos no arquivo utilizando um objeto ObjectOutputStream. Os dados devem ser lidos do arquivo no mesmo formato em que foram gravados no arquivo. Portanto, utilizamos um ObjectInputStream encadeado para um FileInputStream nesse programa.

25

Acesso a Banco de Dados

package com.targettrust.java.capitulo06; import import import import java.awt.*; java.awt.event.*; javax.swing.*; java.io.*;

public class ReadFile extends JFrame { private ObjectInputStream input; private BankUI userInterface; private JButton nextRecord, open; public ReadFile() { super( "Reading a Sequential File of Objects" ); getContentPane().setLayout( new BorderLayout() ); userInterface = new BankUI(); nextRecord = userInterface.getDoTask(); nextRecord.setText( "Next Record" ); nextRecord.setEnabled( false ); nextRecord.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { readRecord(); } } ); addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { if ( input != null ) { closeFile(); } System.exit( 0 ); } } ); open = userInterface.getDoTask2(); open.setText( "Open File" ); open.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { openFile(); } } ); getContentPane().add( userInterface, BorderLayout.CENTER ); validate(); setSize( 300, 200 ); show();

} private void closeFile() { try { input.close(); System.exit( 0 ); }

26

Acesso a Banco de Dados catch ( IOException e ) { JOptionPane.showMessageDialog( this, "Error closing file", "Error", JOptionPane.ERROR_MESSAGE ); System.exit( 1 ); } } public static void main( String args[] ) { new ReadFile(); } private void openFile() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY ); int result = fileChooser.showOpenDialog( this ); if ( result == JFileChooser.CANCEL_OPTION ) { return; } //busca o arquivo selecionado File fileName = fileChooser.getSelectedFile(); if (fileName == null || fileName.getName().trim().equals( "" )){ JOptionPane.showMessageDialog( this,"Invalid File Name", "Invalid File Name",JOptionPane.ERROR_MESSAGE ); } else { try { // ler dados para o input input = new ObjectInputStream( new FileInputStream( fileName ) ); open.setEnabled( false ); nextRecord.setEnabled( true ); } catch ( IOException e ) { JOptionPane.showMessageDialog( this, "Error Opening File", "Error", JOptionPane.ERROR_MESSAGE ); } }

public void readRecord() { BankAccountRecord record; try { record = ( BankAccountRecord ) input.readObject(); String values[] = { String.valueOf( record.getAccount() ), record.getFirstName(), record.getLastName(), String.valueOf( record.getBalance() ) }; userInterface.setFieldValues( values ); } catch ( EOFException eofex ) { nextRecord.setEnabled( false ); JOptionPane.showMessageDialog( this, "No more records in file", "End of File", JOptionPane.ERROR_MESSAGE ); } 27

Acesso a Banco de Dados catch ( ClassNotFoundException cnfex ) { JOptionPane.showMessageDialog( this, "Unable to create object", "Class Not Found", JOptionPane.ERROR_MESSAGE ); } catch ( IOException ioex ) { JOptionPane.showMessageDialog( this, "Error during read from file", "Read Error", JOptionPane.ERROR_MESSAGE ); }

} }

Cdigo 6-9: Classe para ler o arquivo

Como grande parte do cdigo nesse exemplo semelhante ao anterior, discutimos somente as linhas principais do cdigo que so diferentes. Chamamos o mtodo de JFileChooser showOpenDialog para exibir o dilogo Ope n. O comportamento e GUI so os mesmos (exceto que <Save> substitudo por <Open>) como o dilogo exibido por showSaveDialog. Criamos um objeto ObjectInputStream e o atribui a input. O File fileName passado para o construtor FileInputStream que abre o arquivo. O programa l um registro do arquivo toda vez que o usurio clica no boto <Next>. O mtodo readRecord chamado do mtodo actionPerformed Next para ler um registro do arquivo. A instruo chama o mtodo readObject para ler um Object do ObjectInputStream.
28

Acesso a Banco de Dados

Figura 6-4: Janela para ler dados da conta

A fim de utilizar mtodos BankAccountRecord especficos, fazemos a coreo do Object retomado para BankAccountRecord. Se o marcador de fim do arquivo for alcanado durante a leitura, uma EndOfFileException disparada. Para recuperar seqencialmente dados de um arquivo, os programas normalmente comeam a ler a partir do inicio do arquivo e lem todos os dados consecutivamente at que os dados desejados sejam encontrados. Eventualmente necessrio processar o arquivo vrias vezes seqencialmente (a partir do incio do arquivo) durante a execuo de um programa.

Figura 6-5: Janela para seleo de arquivo 29

Acesso a Banco de Dados

A classe FileInputStream no fornece a capacidade de voltar para o comeo do arquivo para Ler o arquivo novamente. O programa CreditInquiry permite que um gerente de crdito exiba informaes das contas dos clientes com saldo zero (isto , clientes que no devem nada empresa), saldos de crdito (isto , clientes para quem a empresa deve dinheiro) e saldos de dbito (isto , clientes que devem dinheiro empresa por bens e servios recebidos no passado).
package com.targettrust.java.capitulo06; import import import import import java.io.*; java.awt.*; java.awt.event.*; java.text.DecimalFormat; javax.swing.*;

public class CreditInquiry extends JFrame { private private private private private private private JTextArea recordDisplay; JButton open, done, credit, debit, zero; JPanel buttonPanel; ObjectInputStream input; FileInputStream fileInput; File fileName; String accountType;

public CreditInquiry(){ super( "Credit Inquiry Program" ); Container c = getContentPane(); c.setLayout( new BorderLayout() ); buttonPanel = new JPanel(); open = new JButton( "Open File" ); open.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { openFile( true ); }} ); buttonPanel.add( open ); credit = new JButton( "Credit balances" ); credit.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { accountType = e.getActionCommand(); readRecords(); } } ); buttonPanel.add( credit ); debit = new JButton( "Debit balances" ); debit.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { 30

Acesso a Banco de Dados accountType = e.getActionCommand(); readRecords();

} ); }

buttonPanel.add( debit ); zero = new JButton( "Zero balances" ); zero.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { accountType = e.getActionCommand(); readRecords(); } } ); buttonPanel.add( zero ); done = new JButton( "Done" ); buttonPanel.add( done ); done.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { if ( fileInput != null ) closeFile(); System.exit( 0 ); } } ); recordDisplay = new JTextArea(); JScrollPane scroller = new JScrollPane( recordDisplay ); c.add( scroller, BorderLayout.CENTER ); c.add( buttonPanel, BorderLayout.SOUTH ); credit.setEnabled( false ); debit.setEnabled( false ); zero.setEnabled( false ); pack(); setSize( 600, 250 ); show();

private void openFile( boolean firstTime ) { if ( firstTime ) { JFileChooser fileChooser = new JFileChooser(); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY ); int result = fileChooser.showOpenDialog( this ); if ( result == JFileChooser.CANCEL_OPTION ) return; fileName = fileChooser.getSelectedFile(); } if ( fileName == null || fileName.getName().equals( "" ) ) JOptionPane.showMessageDialog( this, "Invalid File Name", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); else { try { if ( input != null ) input.close(); fileInput = new FileInputStream( fileName ); input = new ObjectInputStream( fileInput ); open.setEnabled( false ); credit.setEnabled( true ); 31

Acesso a Banco de Dados debit.setEnabled( true ); zero.setEnabled( true );

} }

} catch ( IOException e ) { JOptionPane.showMessageDialog( this, "File does not exist", "Invalid File Name", JOptionPane.ERROR_MESSAGE ); }

private void closeFile() { try { input.close(); } catch ( IOException ioe ) { JOptionPane.showMessageDialog( this, "Error closing file", "Error", JOptionPane.ERROR_MESSAGE ); System.exit( 1 ); } } private void readRecords() { BankAccountRecord record; DecimalFormat twoDigits = new DecimalFormat( "0.00" ); openFile( false ); try { recordDisplay.setText( "The accounts are:\n" ); while ( true ) { record = ( BankAccountRecord ) input.readObject(); if ( shouldDisplay( record.getBalance() ) ) recordDisplay.append( record.getAccount() + "\t" + record.getFirstName() + "\t" + record.getLastName() + "\t" + twoDigits.format( record.getBalance() ) + "\n" ); } } catch ( EOFException eof ) { closeFile(); } catch ( ClassNotFoundException cnfex ) { JOptionPane.showMessageDialog( this, "Unable to create object", "Class Not Found", JOptionPane.ERROR_MESSAGE ); } catch ( IOException e ) { JOptionPane.showMessageDialog( this, "Error reading from file", "Error", JOptionPane.ERROR_MESSAGE ); } } private boolean shouldDisplay( double balance ) { if ( accountType.equals( "Credit balances" ) && balance < 0 ) { return true; } else if (accountType.equals("Debit balances") && balance > 0 ) { return true; 32

Acesso a Banco de Dados } else if (accountType.equals("Zero balances") && balance == 0) { return true; } return false;

} }

public static void main( String args[] ) { CreditInquiry app = new CreditInquiry();

Cdigo 6-10: Classe para ler dados do arquivo

O programa exibe botes que permitem que um gerente de crdito obtenha as informaes de crdito. O boto <Credit> balances produz uma lista de contas com saldos de crdito. O boto <Debit> balances produz uma lista das contas com saldos de dbito. O boto <Zero> balances produz uma lista de contas com saldos zero. O boto <Done> termina a execuo de programa. Os registros so exibidos em uma JTextArea chamada recordDisplay. As informaes de registro so colecionadas lendo o arquivo inteiro e determinando se cada registro satisfaz o critrio para o tipo de conta selecionado pelo gerente de crdito.

Figura 6-5: Tela par ler os dados do arquivo

Clicar em um boto (que no <Done>) configura a varivel accountType com o texto do boto clicado (por exemplo, <Zero> balances etc.) e invoca o mtodo readRecords, que faz um loop pelo arquivo e l cada registro. O mtodo shouldDisplay chamado para determinar se o registro atual satisfaz o tipo de conta solicitado. Se shouldDisplay retornar true, as informaes de conta do registro atual so acrescentadas JTextArea denominada recordDisplay. Quando o marcador de fim do arquivo alcanado, chamamos closeFile para fechar o arquivo.
33

Acesso a Banco de Dados

Gerenciamento de memria: Garbage Collector


O gerenciamento de memria em Java automtico. Quando um objeto criado, uma quantidade de memria alocada para ele no heap. Quando no h mais referncias para este objeto, ele marcado para a coleta de lixo. Quando a coletor de lixo executa, ele procura por objetos marcados e retorna a memria usada por tais objetos para o heap. No h funes free() ou delete() em Java, tal como elas existem em C++. Para forar a marcao de um objeto simplesmente remova todas as referncias para este objeto, atribuindo null para todas as referncias. O coletor de lixo executa quando a quantidade de memria livre disponvel para a JVM cai abaixo de um valor arbitrrio de limiar. A JVM realiza a coleta de lixo atravs de uma thread de baixa prioridade. Quando a JVM no tem mais nada a fazer, a thread do coletor de lixo recebe algum tempo de CPU procurando descobrir se h memria que possa ser liberada. Voc pode simplesmente pedir que o coletor de lixo execute chamando o mtodo gc() da classe System. Entretanto, isto apenas um pedido para que a coleta de lixo se realize. No h garantias que a JVM aceita a sugesto.

34

Acesso a Banco de Dados

Exerccios
1. Agora que voc j viu a parte de arquivos, vamos dicionar na nossa aplicao que est sendo desenvolvida neste curso o recurso de serializao de objetos bem como o de gravao em arquivos texto. Os dados da aplicao sero salvos em um objeto persistente para que voc possa recuperar os memos mais adiante. Para contemplar a parte de arquivos texto, voc deve criar um mecanismo de log para a sua aplicao e salvar linhas de texto que registram as principais aes do usurio em um arquivo texto. Siga as instrues do instrutor para realizar este exerccio.

35

7. Acesso a Banco de Dados

Objetivos
Conectar um banco de dados usando Java Database Connectivity (JDBC) Criar e executar uma query usando JDBC Executar comandos Efetuar commit e rollback de transaes

Acesso a Banco de Dados

Introduo
Neste captulo estudaremos o modo de acesso ao banco de dados utilizando JDBC. Como vimos anteriormente, o Java Database Connectivity (JDBC) faz parte do pacote java.sql na qual contm um conjunto de interfaces que especificam o JDBC API. Este pacote faz parte do Java 1.1.7 e Java 2. JDBC 1.0 (JDK 1.1) JDBC 2.0 (JDK 2) JDBC 3.0 (JDK 1.4) Um driver JDBC implementa o cdigo de conexo e query especficas para o banco de dados. Os drivers da Oracle/IBM provem extenses para suportar datatypes especiais dos bancos de dados. A Oracle e IBM provem trs drivers: Thin client Driver Client-based Driver Server-based Driver

Acesso a Banco de Dados

JDBC Drivers
Thin Client Driver
Este driver escrito completamente em Java, e pode ser carregado por um browser Web. o nico driver que no requer nenhuma instalao no lado cliente, assim sendo, voc tem que usar este driver se voc estiver desenvolvendo um applet. Este driver pode conectar qualquer banco de dados Oracle7 ou um banco de dados Oracle8i/9i. Voc deve usar este driver se voc estiver desenvolvendo uma aplicao que pode conectar diferentes verses do banco. Por comunicar com o banco de dados, o driver usa uma verso leve do SQL*Net ou Net8 em cima da camada TCP/IP que pode ser carregado em tempo de execuo.

Acesso a Banco de Dados

Client Based Drivers


H trs drivers: o OCI 7 para Oracle7, o OCI 8 para Oracle8/8i e OCI 9 para Oracle 9i. Cada um dos drivers OCI que usa uma biblioteca de ligao dinmica (DLL) deve ser instalado no sistema do cliente. Estes drivers convertem chamadas de JDBC Oracle Call Interface (OCI). As chamadas de OCI so enviadas por SQL*Net ou Net8/9 para o banco de dados. Voc deve usar um dos drivers OCI se voc est desenvolvendo um cliente ou uma aplicao no servidor de aplicao e precisa do mximo de performance. No caso IBM existe o driver Client DB2.

Acesso a Banco de Dados

Server-Side Driver
Este driver permite o Java Stored Procedures comunicar-se diretamente com a SQL Engine. O driver comunica-se usando uma biblioteca C. JDBC, o driver, a biblioteca C e a SQL engine so executado no mesmo local isso significa que no h nenhuma utilizao da rede. O driver pode ser usado por qualquer programa Java executado no RDBMS; isto inclui Stored Procedures, Enterprise JavaBeans, e Servlets Java.

Acesso a Banco de Dados

Outros Drivers de JDBC


JDBC-ODBC Bridge a ponte JDBC-ODBC um driver JDBC desenvolvido pela JavaSoft. Permite programas Java usar JDBC com drivers de ODBC existentes. JavaSoft no suporta mais este driver. Agora, j temos drivers em Java para os principais bancos. ODBC (Open Database Connectivity) uma API unificada para conectar bancos de dados SQL. Foi projetado para permitir o desenvolvimento de aplicaes independentes de banco de dados.

Acesso a Banco de Dados

Aplicao vs JDBC Driver


Tipo de Programa Applet Client application Driver Thin Client Thin EJB, servlet (on the middle tier) EJB, servlet (in the database) Stored Procedure Client Thin Server Side Server Side

Tabela 7-1: Tipos de drivers e seus usos

Acesso a Banco de Dados

JDBC URLs
JDBC usa uma URL para identificar a conexo de banco de dados. A URL de um JDBC um pouco diferente de uma URL de HTTP ou FTP, mas como qualquer URL, um localizador de recursos, neste caso, de um banco de dados. A estrutura de um URL de JDBC flexvel, permitindo assim que cada jdbc:<subprotocol>:<subname>
* <subprotocol> o nome do driver ou mecanismo de conexo ao banco de dados. * <subname> identifica o banco de dados. <driver>:@<database>

* jdbc o protocolo. Todos os URLs comeam com o protocolo

desenvolvedor especifique o tipo de driver no URL.

Acesso a Banco de Dados

Thin Driver
jdbc:oracle:thin:@<host>:<porta>:<SID> <driver>: thin <database>: uma strinig formada por <host>:<port>:<sid>

Por exemplo:

jdbc:oracle:thin:@edihost:1521:ORCL

jdbc:db2://<host>:<porta>/<DBName> <driver>: thin (IBM) <database>: uma strinig formada por <host>:<port>/<DBName>.

Por exemplo:

jdbc:db2://serverHostname:port/databaseName

Acesso a Banco de Dados

OCI Driver
jdbc:oracle:oci8:@<TNSNAMES> <driver> oci8/oci7, dependende de qual driver utilizado. <database> uma entrada de TNSNAMES no arquivo de tnsnames.ora.

Por exemplo: jdbc:oracle:oci8:@eduhost

10

Acesso a Banco de Dados

Server Side Driver


jdbc:oracle:DBName <driver> DBName. Voc no especifica um banco de dados, porque o driver amarrado a um banco de dados especfico.

jdbc:db2:DBName <driver> DBName. Voc no especifica um banco de dados, porque o driver amarrado a um banco de dados especfico.

O Banco de Dados local. Neste caso, necessrio informar o nome da instncia do BD.

11

Acesso a Banco de Dados

Acessando Bases de Dados por JDBC


Existem quatro etapas no processo de query a um banco de dados relacional: Connect Query Process Results Close

12

Acesso a Banco de Dados

Etapa 1: Connect
Para criar uma conexo voc precisa seguir os seguintes passos: Importar o pacote JDBC Registrar o driver Connectar com o banco de dados

import java.sql.*; DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver()); Connection conn = DriverManager.getConnection(URL, userId, password);

13

Acesso a Banco de Dados

Carregando o Driver
Drivers JDBC so registrados pelo DriverManager. H dois modos para fazer isto: Use o mtodo registerDriver() do DriverManager Use o mtodo forName() da classe java.lang.Class para carregar os drivers JDBC diretamente, como segue:
Class C = class.forName (oracle.jdbc.driver.OracleDriver); //Ou Class C = class.forName (COM.ibm.db2.jdbc.net.DB2Driver);

14

Acesso a Banco de Dados

Excees
Ao usar JDBC, a maioria dos mtodos possuem excees, capazes de contornar qualquer coisa que der errado. Class.forClass() executa uma ClassNotFoundException se a classe especificada no poder ser encontrada. Voc tem que tratar esta exceo em seu cdigo.

O mtodo getConnection() executa um SQLException se houver qualquer problema, como um protocolo invlido, um nome de usurio e/ou senha incorreta. O SQLException prov a informao seguinte: Uma string descreve o erro X/Open SQLState Um cdigo de erro especfico

15

Acesso a Banco de Dados

Etapa 2: Query
Cria o comando Executa a query

16

Acesso a Banco de Dados

Statement
Um objeto Statement envia seu comando SQL para banco de dados. Voc precisa de uma conexo ativa para criar uma declarao de JDBC. A Declarao tem dois mtodos para executar uma query no banco de dados: executeQuery () para QUERY executeUpdate() para INSERT, UPDATE, DELETE, ou declarao de DDL JDBC prov dois outros objetos de declarao: PregaredStatement para precompio de declaraes SQL. CallableStatement para declaraes que executam Stored Procedures.

17

Acesso a Banco de Dados

Objetos e Interfaces
java.sql.Statement uma interface, no um objeto. Quando voc declara o objeto Statement, e inicializa este usando o mtodo CreateStatement(), voc est criando a implementao da interface de declarao provido pelo driver Oracle.

18

Acesso a Banco de Dados

Criando uma Query


Crie um objeto de declarao vazio Execute a query Por exemplo: Statement stmt = conn.createStatement (); ResultSet rset = stmt.executeQuery (select * from emp);

statement stmt = conn.createStatementy(); ResultSet rset = stmt.executeQuery(statement); ResultSet rset = stmt.executeUpdate(statement);

19

Acesso a Banco de Dados

Etapa 3: Process results


Preparando o conjunto do resultado Disponibilizando variveis Java com o resultado

20

Acesso a Banco de Dados

ResultSet
O JDBC devolve os resultados de uma query em um objeto ResultSet. Um ResultSet mantm um cursor que aponta o seu registro atual. Use next() para navegar pelos registros. A classe de ResultSet tem vrios mtodos que retornam valores de coluna no registro corrente. Cada mtodo getXXX() tenta converter o valor da coluna ao tipo Java especificado. Por exemplo, getInt() pega o valor da coluna como um int, getString() pega o valor da coluna como uma String, e getDate() retorna o valor de coluna como uma Data. Cada mtodo getXXX() tm duas verses, permitindo para o programador especificar a coluna atravs de nmero ou atravs de nome. Colunas especificadas atravs do nmero: as colunas so numeradas de 1 X. Colunas especificandas atravs de nome: os nomes de colunas so case insensitive. Para query que no foi especificado o nome da coluna melhor usar nmeros de coluna. ResultSet prov um mtodo chamado findColumn() que devolve o nmero da coluna para um determinado nome de coluna. O mtodo getString() pode ser usado para recuperar qualquer tipo de dados. o mtodo mais fcil para ser usado em aplicaes visuais, quando se quer exibir ou imprimir os dados. Tambm pode ser usado quando o usurio monta o comando SQL de alterao utilizando a declarao SQL UPDATE. Todos os mtodos getXXX() requerem um nico parmetro, com exceo de getBigDecimal (colname, scale) e getBigDecimal (colindex, scale), ambos requerem no segundo parmetro o nmero de casas decimais.

21

Acesso a Banco de Dados

Processando os Resultados
Navegue pelo conjunto de dados utilizando o mtodo getXXX() para retornar o valor de cada coluna. while (rset.next ( ) ) {...} String val = rset.getString (colname); ou String val = rset.getString (colindex);

Por exemplo: while (rset.next ( ) ) { String title = rset.getString(TITLE); String year = rset.getString(YEAR); ... / / Processamento }

22

Acesso a Banco de Dados

Etapa 4: Close
Encerrando a interao com o banco de dados

23

Acesso a Banco de Dados

24

Acesso a Banco de Dados

Fechando uma Conexo


Voc tem que fechar todo o ResultSet explicitamente como tambm sua declarao. O mtodo close() limpa a memria e os cursores de banco de dados, assim se voc no fecha seu ResultSet explicitamente e sua declarao, voc pode ter srios problemas de memria. O driver no servidor roda em uma sesso default, ou seja, voc j est conectado e no pode fechar a conexo. Chamando o mtodo close(), neste caso, no acontece nada. Atravs deste exemplo abaixo podemos analisar todos o funcionamento de um programa Java acessando um banco de dados Oracle utilizando o driver de JDBC.

25

Acesso a Banco de Dados

MetaData
Metadata (java.sql.DatabaseMetaData) um objeto de informaes dos dados. Em JDBC voc usa o mtodo Connection.getMetaData() para retornar um objeto de DatabaseMetaData. A classe de DatabaseMetaData contm mais de cem mtodos para obter informao sobre um banco de dados. Alguns exemplos de mtodos DatabaseMetaData: getColumnPrivileges(): retorna a descrio do direito de acesso da coluna de uma tabela. getColumns(): Retorna uma descrio das colunas de tabela. getDatabaseProductName(): Retorna o nome do banco de dados. getDriverName(): Retorna o nome deste driver JDBC. storesLowerCaseIdentifiers(): o banco de dados armazena minsculas e maisculas. Pode executar SQL em minscula? supportsAlterTableWithAddColumn(): colunas? ALTER TABLE pode adicionar

supportsFullOuterJoins(): Suporta OuterJoins?

26

Acesso a Banco de Dados

Tipo de Dados
A classe java.sql.Types define constantes que so usadas para identificar tipos de SQL ANSI. ResultSetMetaData.getColumnType() retorna o valor correspondente de uma destas constantes. Em muitos casos, voc pode adquirir todas as colunas em seu resultado usando getObject() ou getString() do ResultSet. Por razes de desempenho, ou porque voc quer executar clculos complexos, s vezes importante ter seus dados em seu tipo real. ANSI SQL
CHAR, VARCHAR2 LONGVARCHAR NUMERIC, DECIMAL BIT TINYINT SMALLINT INTEGER BIGINT REAL DOUBLE, FLOAT BINARY, VARBINARY LONGVARBINARY DATE TIME TIMESTAMP mal Boolean Byte Short Int Long Float Double byte [ ] byte [ ] java.sql.Date java.sql.Time java.sql.Timestamp getBoolean( ) getByte( ) getShort( ) getInt( ) getLong( ) getFloat( ) getDouble( ) getBytes( ) getBinaryStream( ) getDate( ) getTime( ) getTimestamp( )

Java Type
java.lang.String java.langString java.math.BigDeci

ResultSet Method
getString( ) getAsciiStream( ) getBigDecimal( )

27

Acesso a Banco de Dados

Resumo Tecnologia JDBC


DriverManager
DriverManager prov acesso a drivers JDBC registrados. DriverManager entrega conexes a uma fonte de dados especificada por seu mtodo getConnection().

Connection
A classe Connection disponibilizada pelo driver JDBC. A Connection representa uma sesso com um banco de dados. A Conexo usada para criar um objeto Statement, usando createStatement().

Statement
Statement executa comandos SQL. Por exemplo, podem ser executadas querys usando o mtodo executeQuery() e os resultados so disponibilizados em ResultSet.

ResultSet
JDBC devolve os resultados de uma query em um objeto de ResultSet. Um ResultSet mantm um cursor. O mtodo next() move o cursor para o prximo registro. ResultSet tem mtodos getXXX() para recuperar valores de colunas.

DatabaseMetaData e ResultSetMetaData
DatabaseMetaData e ResultSetMetaData devolvem metadata sobre o banco de dados e ResultSet respectivamente. Chame getMetaData() na Connection ou no ResultSet.

28

Acesso a Banco de Dados

Acessando Bases de Dados com JDBC


O programa abaixo ilustra a conexo com o banco de dados, a consulta ao banco de dados e a exibio dos resultados. A seguinte discusso apresenta os aspectos-chave de JDBC do programa.
package com.targettrust.java.capitulo07; import import import import import java.sql.*; javax.swing.*; java.awt.*; java.awt.event.*; java.util.*;

public class TableDisplay extends JFrame { private Connection connection; private JTable table; public TableDisplay() { /* URL para conexes com outros bancos * Sintaxe: jdbc:db2://serverHostname:port/databaseName (REMOTE) 10.0.0.30:6790/sample (STARTAR APPLET SERVER) * String url = "jdbc:db2://10.0.2.12:6789/sample"; */ String url = "jdbc:oracle:thin:@127.0.0.1:1521:ORADB"; String username = "target"; String password = "target"; try{ /* Conexo com outros bancos * Class.forName( "COM.ibm.db2.jdbc.app.DB2Driver"); * Class.forName( "COM.ibm.db2.jdbc.net.DB2Driver"); * Class.forName( "org.postgresql.Driver"); *** * Criao de um objeto do driver: * DriverManager.registerDriver( new org.postgresql.Driver() ); */ Class.forName( "oracle.jdbc.driver.OracleDriver"); connection = DriverManager.getConnection( url, username, password ); connection.setAutoCommit(false); } catch ( ClassNotFoundException cnfex ){ System.err.println( "Failed to load JDBC/ODBC driver." ); cnfex.printStackTrace(); System.exit( 1 ); // terminate program } catch ( SQLException sqlex ){ try { System.err.println( "Unable to connect" ); 29

Acesso a Banco de Dados if( connection != null ) connection.close(); sqlex.printStackTrace();

} catch (SQLException e) {}

getTable(); setTitle("Oracle Connection"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize( 450, 150 ); setVisible(true); } private void displayResultSet( ResultSet rs ) throws SQLException { boolean moreRecords = rs.next(); if ( ! moreRecords ){ JOptionPane.showMessageDialog( this, "ResultSet contained no records" ); return; } Vector columnHeads = new Vector(); Vector rows = new Vector(); try { ResultSetMetaData rsmd = rs.getMetaData(); for ( int i = 1; i <= rsmd.getColumnCount(); ++i ) columnHeads.addElement( rsmd.getColumnName( i ) ); do { rows.addElement( getNextRow( rs, rsmd ) ); } while ( rs.next() ); table = new JTable( rows, columnHeads ); JScrollPane scroller = new JScrollPane( table ); getContentPane().add( scroller, BorderLayout.CENTER ); validate();

} private Vector getNextRow( ResultSet rs, ResultSetMetaData rsmd ) throws SQLException { Vector currentRow = new Vector(); for ( int i = 1; i <= rsmd.getColumnCount(); ++i ) switch( rsmd.getColumnType( i ) ) { case Types.VARCHAR: currentRow.addElement( rs.getString( i ) break; case Types.INTEGER: currentRow.addElement( new Long( rs.getLong( i ) ) break; case Types.DATE: currentRow.addElement( rs.getString( i ) break; default: currentRow.addElement( rs.getString( i ) } return currentRow; } 30

} catch ( SQLException sqlex ){ sqlex.printStackTrace(); }

); ); ); );

Acesso a Banco de Dados private void getTable(){ Statement statement= null; ResultSet resultSet = null; try { String query = "SELECT * FROM Emp"; statement = connection.createStatement(); resultSet = statement.executeQuery( query ); displayResultSet( resultSet ); } catch ( SQLException sqlex ) { try { statement.close(); connection.close(); sqlex.printStackTrace(); } catch (SQLException e) {} }

public static void main( String args[] ) { final TableDisplay app = new TableDisplay(); } public void shutDown() { try { connection.close(); } catch ( SQLException sqlex ) { System.err.println( "Unable to disconnect" ); sqlex.printStackTrace(); } } } Cdigo 7-1: Classe para listar dados de uma tabela

Importamos o pacote java.sql que contm as classes e interfaces para manipular os bancos de dados relacionais em Java. Declaramos uma referncia Connection (pacote java.sql) chamada connection. Isso ir referenciar um objeto que implementa a interface Connection. Um objeto Connection gerencia a conexo entre o programa Java e o banco de dados. Tambm fornece suporte para executar instrues de SQL para fins de manipulao do banco de dados e o processamento de transaes. O construtor para a classe TableDisplay tenta a conexo com o banco de dados e, se bem-sucedido, consulta o banco de dados e exibe os resultados chamando o mtodo utilitrio getTable. Especificamos a URL (Uniform Resource Locator) do banco de dados que ajuda o programa a localizar o banco de dados (possivelmente em uma rede ou no sistema de arquivos local do computador), o nome de usurio para efetuar logon no banco de dados e a senha para efetuar logon no banco de dados.
31

Acesso a Banco de Dados

A URL especifica o protocolo para comunicao (JDBC), o subprotocolo para comunicao (ODBC) e o nome do banco de dados (ODBC). O subprotocolo ODBC indica que o programa estar utilizando JDBC para conectar-se com uma fonte de dados Mcrosoft ODBC. ODBC uma tecnologia desenvolvida pela Microsoff para permitir acesso genrico a diferentes sistemas de bancos de dados na plataforma Windows (e algumas plataformas UNIX). O Java 2 Software Development Kit (J2SDK) fornece o driver de banco de dados de ponte JDBC para ODBC a fim de permitir que qualquer programa Java acesse qualquer fonte de dados ODBC. O driver definido pela classe JdbcOdbcDriver no pacote sun.jdbc.odbc.

Figura 7-1: Listagem de dados da tabela

A definio de classe para o driver de banco de dados deve ser carregada antes do programa se conectar ao banco de dados. Utilizamos o mtodo static forName da classe Class (pacote java.lang) para carregar a definio de classe para o driver de banco de dados (essa linha dispara uma exceo ClassNotFoundException se a classe no conseguir ser localizada). Observe que a instruo especifica o nome completo do pacote e o nome da classe - sun.jdbc.odbcJdbcOdbcDriver. Para mais informaes sobre drivers JDBC e bancos de dados suportados visite o site JDBC da Sun Microsystems na Web: http://java.sun. com/products/jdbc/ Utilizamos o mtodo static getConnection da classe DriverManager (pacote java.sql) para tentar uma conexo com o banco de dados especificado pela URL. Os argumentos username e password so passados aqui porque intencionalmente configuramos a fonte de dados para exigir que o usurio
32

Acesso a Banco de Dados

efetue login. Nosso banco de dados configurado com um nome de usurio anonymous - e uma senha guest - para propsitos de demonstrao. Se o DriverManager no se conectar ao banco de dados, o mtodo getConnection dispara uma SQLException. Se a tentativa de conexo bemsucedida, chamamos o mtodo utilitrio getTable para recuperar os dados da tabela EMP. O mtodo utilitrio getTable consulta o banco de dados e, a seguir, chama o mtodo utilitrio displayResultSet pala criar uma JTable (pacote java.swing) contendo o resultado da consulta. Declaramos uma referncia Statement (pacote java.sql) que ir se referir a um objeto que implementa a interface Statement. Esse objeto submeter a consulta ao banco de dados. Declaramos uma referncia ResultSet (pacote java.sql) que ir se referir a um objeto que implementa a interface ResultSet. Quando uma consulta realizada em um banco de dados, um objeto ResultSet retomado contendo o resultado da consulta. Os mtodos da interface ResultSet permitem ao programador manipular os resultados da consulta. Definimos a consulta a realizar. Nesse exemplo, selecionaremos todos os registros da tabela EMP (Empregados). Invocamos o mtodo createStatement de Connection para obter um objeto que implementa a interface Statement. Agora podemos utilizar statement para consultar o banco de dados. Realizamos a consulta chamando o mtodo executeQuery de Statement. Esse mtodo retorna um objeto que implementa ResultSet e contm os resultados da consulta, O ResultSet passado para o mtodo utilitrio displayResultSet, assim a instruo fechada para indicar que terminamos o processamento da consulta. O mtodo displayResultSet posiciona-se no primeiro registro no ResultSet. Com o mtodo next de ResultSet. Inicialmente, o ResultSet posicionado antes do primeiro registro, portanto esse mtodo deve ser chamado antes de voc conseguir acessar os resultados. O mtodo next retorna um boolean indicando se foi capaz de posicionar no prximo registro. Se o mtodo retoma false, no h mais registros a processar. Se houver registros, definimos um Vector para armazenar os nomes de coluna das colunas no ResultSet e defimos outro Vector para armazenar as linhas de dados do ResultSet. Esses Vectors so utiliiados com o construtor JTable para construir uma JTable que exibe os dados do ResultSet. Obtemos os meta dados para o ResultSet os atribui a uma referncia ResultSetMetaData (pacote java.sql) Os meta dados para o ResultSet descrevem o contedo de um ResultSet. Essas informaes podem a ser utilizadas para obter programaticamente informaes sobre os nomes e tipos das colunas ResultSet e podem ajudar o programador a processar um ResultSet dinamicamente quando informaes
33

Acesso a Banco de Dados

detalhadas sobre o ResultSet no so conhecidas antes da consulta. Utilizamos ResultSetMetaData para recuperar os nomes de cada coluna no ResultSet. O mtodo getcolumnCount de ResultSetMetaData retoma o nmero de colunas no ResultSet e mtodo getColumnName de ResultSetMetaData retoma o nome da coluna especificada. Recuperamos cada linha do ResultSet utilizando o mtodo utilitrio getNextRow. O mtodo getNextRow retoma um Vector contendo os dados de uma linha do ResultSet. Repare na condio rs.next(). Isso move o cursor de ResultSet que monitora o registro atual no ResultSet para o prximo registro no ResultSet. Lembre-se de que o mtodo next retorna falso quando no h mais registros no ResultSet. Portanto, o comando terminar quando no houver mais registros. Depois que todas as linhas so convertidas em Vectors, criamos o componente GUI JTab1e que exibe os registros no ResultSet. O construtor que utilizamos nesse programa recebe dois Vectors como argumentos. O primeiro argumento um Vector de Vectors (semelhante a um array bidimensional) que contm todos os dados de linhas, O segundo argumento um Vector contendo os nomes de coluna para cada coluna. O construtor JTable utiliza esses Vectors para preencher a tabela. O mtodo getNextRow recebe um ResultSet e seu correspondente ResultgetMetaData como argumentos e cria um Vector contendo uma linha de dados do ResultSet. A estrutura for faz um loop por cada coluna do conjunto de resultados e executa a estrutura switch que determina o tipo de dados da coluna. O mtodo getColumnType de ResultSetMetaData retorna uma constante inteira da classe Types (pacote java.sql) indicando o tipo dos dados. Os nicos tipos de dados em nosso banco de dados so Strings e inteiros longos. O tipo de SQL para strings Types * VARCHAR e o tipo de SQL para inteiros longos Types * INTEGER. Utilizamos o mtodo getString de ResultSet para obter o String de uma coluna do tipo Types - VARCHAR. Utilizamos o mtodo getLong de ResultSet para obter o inteiro longo de uma coluna do tipo Types - INTEGER. O mtodo shutdown fecha a conexo para o banco de dados com o mtodo close de Connection.

34

Acesso a Banco de Dados

Registrando Fonte de Dados de ODBC


O exemplo anterior pressupe que o banco de dados ODBC j foi registrado como uma fonte de dados ODBC. Para conectar-se ao banco de dados, uma fonte de dados ODBC deve estar registrada no sistema pela opo ODBC Data Sources no Control Panel do Windows. D um clique duplo nessa opo para exibir a caixa de dilogo ODBC Data Source Administrator. Esse dilogo utilizado para registrador nosso User Data Source Name (User DSN). Certifique-se de que a guia User DSN esteja selecionada, ento clique em Add para exibir o dilogo Create new Data Source. Como estamos utilizando um banco de dados do Microsoft Access, selecionamos Microsoft Access Driver e clicamos em Finish. O dilogo ODBC Microsoft Access Setup aparece. Inserimos o nome (por exemplo, Banco) que utilizaremos para referenciar o banco de dados com JDBC no campo de texto Data Source Name. Voc tambm pode inserir uma descrio. Clique no boto <Select> para exibir o dilogo Select Database.

35

Acesso a Banco de Dados Figura 7-2: Criando uma fonte de dados no windows

Utilize esse dilogo para localizar e selecionar o arquivo de banco de dados MDB em seu sistema (ou na rede). Quando tiver terminado, clique em <OK> para fechar o dilogo Select Database e retomar ao dilogo ODBC Microsott Access Setup. A seguir, clique no boto <Advanced> para exibir o dilogo Set Advanced Options. Digite o nome de usurio anonymous e a senha guest nos campos na parte superior do dilogo, ento clique em <OK> para fechar o dilogo. Clique em <OK> para fechar o dilogo ODBC Microsoft Access. Repare que o dilogo ODBC Data Source Administrator agora contm a origem de dados Banco. Clicar em <OK> para fechar o dilogo. Estamos agora prontos para acessar a origem de dados ODBC pelo driver de ponte de JDBC para ODBC. Execute o programa anterior para exibir o contedo da tabela EMP do banco de dados MDB.

36

Acesso a Banco de Dados

Manipulando Banco de Dados com ODBC


O prximo exemplo manipula um banco de dados que contm uma tabela (Address). O programa fornece recursos para inserir novos registros, atualizar registros existentes e procurar registros no banco de dados.

package com.targettrust.java.capitulo07; import import import import java.sql.*; java.awt.*; java.awt.event.*; javax.swing.*;

public class AddressBook extends JFrame { private ControlPanel controls; private ScrollingPanel scrollArea; private JTextArea output; private String url; private Connection connect; private JScrollPane textpane; public AddressBook() { super( "Address Book Database Application" ); Container c = getContentPane(); scrollArea = new ScrollingPanel(); output = new JTextArea( 6, 30 ); c.setLayout( new BorderLayout() ); c.add( new JScrollPane( scrollArea ), BorderLayout.CENTER ); textpane = new JScrollPane( output ); c.add( textpane, BorderLayout.SOUTH ); try { url = "jdbc:odbc:AddressBook"; Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); connect = DriverManager.getConnection( url ); output.append( "Connection successful\n" ); } catch ( ClassNotFoundException cnfex ) { cnfex.printStackTrace(); output.append( "Connection unsuccessful\n" + cnfex.toString() ); } catch ( SQLException sqlex ) { sqlex.printStackTrace(); output.append( "Connection unsuccessful\n" + sqlex.toString() ); } catch ( Exception ex ) { ex.printStackTrace(); output.append( ex.toString() ); } controls = new ControlPanel( connect, scrollArea, output); c.add( controls, BorderLayout.NORTH ); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 37

Acesso a Banco de Dados setSize( 500, 500 ); setVisible(true);

public static void main( String args[] ) { AddressBook app = new AddressBook(); } }

package com.targettrust.java.capitulo07; import import import import java.awt.*; java.awt.event.*; java.sql.*; javax.swing.*;

public class AddRecord implements ActionListener { private ScrollingPanel fields; private JTextArea output; private Connection connection; public AddRecord( Connection c, ScrollingPanel f, JTextArea o ) { connection = c; fields = f; output = o; } public void actionPerformed( ActionEvent e ) { try { Statement statement = connection.createStatement(); if ( !fields.last.getText().equals( "" ) && !fields.first.getText().equals( "" ) ) { String query = "INSERT INTO addresses (" + "firstname, lastname, address, city, " + "stateorprovince, postalcode, country, " + "emailaddress, homephone, faxnumber" + ") VALUES ('" + fields.first.getText() + "', '" + fields.last.getText() + "', '" + fields.address.getText() + "', '" + fields.city.getText() + "', '" + fields.state.getText() + "', '" + fields.zip.getText() + "', '" + fields.country.getText() + "', '" + fields.email.getText() + "', '" + fields.home.getText() + "', '" + fields.fax.getText() + "')"; output.append( "\nSending query: " + connection.nativeSQL( query ) + "\n" ); int result = statement.executeUpdate( query ); if ( result == 1 ) output.append( "\nInsertion successful\n" ); else { output.append( "\nInsertion failed\n" ); fields.first.setText( "" ); fields.last.setText( "" ); 38

Acesso a Banco de Dados fields.address.setText( "" ); fields.city.setText( "" ); fields.state.setText( "" ); fields.zip.setText( "" ); fields.country.setText( "" ); fields.email.setText( "" ); fields.home.setText( "" ); fields.fax.setText( "" );

} } else output.append( "\nEnter at least first and last name then press Add\n" ); statement.close(); } catch ( SQLException sqlex ) { sqlex.printStackTrace(); output.append( sqlex.toString() ); }

} }

Cdigo 7-3: Conectando com a ponte JDBC-ODBC

39

Acesso a Banco de Dados

package com.targettrust.java.capitulo07; import import import import java.awt.*; java.awt.event.*; java.sql.*; javax.swing.*;

public class FindRecord implements ActionListener { private ScrollingPanel fields; private JTextArea output; private Connection connection; public FindRecord( Connection c, ScrollingPanel f, JTextArea o ) { connection = c; fields = f; output = o; } public void actionPerformed( ActionEvent e ) { try { if ( !fields.last.getText().equals( "" ) ) { Statement statement = connection.createStatement(); String query = "SELECT * FROM addresses " + "WHERE lastname = '" + fields.last.getText() + "'"; output.append( "\nSending query: " + connection.nativeSQL( query ) + "\n" ); ResultSet rs = statement.executeQuery( query ); display( rs ); output.append( "\nQuery successful\n" ); statement.close(); } else fields.last.setText( "Enter last name here then press Find" ); } catch ( SQLException sqlex ) { sqlex.printStackTrace(); output.append( sqlex.toString() ); } } public void display( ResultSet rs ) { try { if(rs.next()) { fields.id.setText( String.valueOf( rs.getInt( 1 ) ) ); fields.first.setText( rs.getString( 2 ) ); fields.last.setText( rs.getString( 3 ) ); fields.address.setText( rs.getString( 4 ) ); fields.city.setText( rs.getString( 5 ) ); fields.state.setText( rs.getString( 6 ) ); fields.zip.setText( rs.getString( 7 ) ); fields.country.setText( rs.getString( 8 ) ); fields.email.setText( rs.getString( 9 ) ); fields.home.setText( rs.getString( 10 ) ); fields.fax.setText( rs.getString( 11 ) );

output.append( "\nNo record found\n" ); } catch ( SQLException sqlex ) { sqlex.printStackTrace(); output.append( sqlex.toString() ); } } 40

} else

Acesso a Banco de Dados }

package com.targettrust.java.capitulo07; import import import import java.awt.*; java.awt.event.*; java.sql.*; javax.swing.*;

public class UpdateRecord implements ActionListener { private ScrollingPanel fields; private JTextArea output; private Connection connection; public UpdateRecord( Connection c, ScrollingPanel f, JTextArea o ) { connection = c; fields = f; output = o; } public void actionPerformed( ActionEvent e ) { try { Statement statement = connection.createStatement(); if ( !fields.id.getText().equals( "" ) ) { String query = "UPDATE addresses SET " + "firstname='" + fields.first.getText() + "', lastname='" + fields.last.getText() + "', address='" + fields.address.getText() + "', city='" + fields.city.getText() + "', stateorprovince='" + fields.state.getText() + "', postalcode='" + fields.zip.getText() + "', country='" + fields.country.getText() + "', emailaddress='" + fields.email.getText() + "', homephone='" + fields.home.getText() + "', faxnumber='" + fields.fax.getText() + "' WHERE id=" + fields.id.getText(); output.append( "\nSending query: " + connection.nativeSQL( query ) + "\n" ); int result = statement.executeUpdate( query ); if ( result == 1 ) output.append( "\nUpdate successful\n" ); else { output.append( "\nUpdate failed\n" ); 41

Acesso a Banco de Dados fields.first.setText( "" ); fields.last.setText( "" ); fields.address.setText( "" ); fields.city.setText( "" ); fields.state.setText( "" ); fields.zip.setText( "" ); fields.country.setText( "" ); fields.email.setText( "" ); fields.home.setText( "" ); fields.fax.setText( "" );

statement.close(); } else output.append( "\nYou may only update an " + "existing record. Use Find to " + "locate the record, then " + "modify the information and " + "press Update.\n" ); } catch ( SQLException sqlex ) { sqlex.printStackTrace(); output.append( sqlex.toString() ); }

} }

package com.targettrust.java.capitulo07; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Help implements ActionListener { private JTextArea output; public Help( JTextArea o ) { output = o; } public void actionPerformed( ActionEvent e ) { output.append( "\nClick Find to locate a record.\n" + "Click Add to insert a new record.\n" + "Click Update to update " + "the information in a record.\n" + "Click Clear to empty" + " the textfields.\n" ); }

42

Acesso a Banco de Dados

package com.targettrust.java.capitulo07; import import import import java.awt.*; java.awt.event.*; java.sql.*; javax.swing.*;

public class ControlPanel extends JPanel { private JButton findName, addName,updateName, clear, help; public ControlPanel( Connection c, ScrollingPanel s, JTextArea t ) { setLayout( new GridLayout( 1, 5 ) ); findName = new JButton( "Find" ); findName.addActionListener( new FindRecord( c, s, t ) ); add( findName ); addName = new JButton( "Add" ); addName.addActionListener( new AddRecord( c, s, t ) ); add( addName ); updateName = new JButton( "Update" ); updateName.addActionListener( new UpdateRecord( c, s, t ) ); add( updateName ); clear = new JButton( "Clear" ); clear.addActionListener( new ClearFields( s ) ); add( clear ); help = new JButton( "Help" ); help.addActionListener( new Help( t ) ); add( help );

} }

package com.targettrust.java.capitulo07; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ScrollingPanel extends JPanel { private JPanel labelPanel, fieldsPanel; private String labels[] = { "ID number:", "First name:", "Last name:", "Address:", "City:", "State/Province:", "PostalCode:", "Country:", "Email:", "Home phone:", "Fax Number:" }; JTextField id, first, last, address, city, state, zip, country, email, home, fax; public ScrollingPanel() { labelPanel = new JPanel(); labelPanel.setLayout( new GridLayout( labels.length, 1 ) ); for ( int i = 0; i < labels.length; i++ ) { labelPanel.add( new JLabel( labels[ i ]) ); 43

Acesso a Banco de Dados } fieldsPanel = new JPanel(); fieldsPanel.setLayout( new GridLayout( labels.length, 1 ) ); id = new JTextField( 20 ); id.setEditable( false ); fieldsPanel.add( id ); first = new JTextField( 20 ); fieldsPanel.add( first ); last = new JTextField( 20 ); fieldsPanel.add( last ); address = new JTextField( 20 ); fieldsPanel.add( address ); city = new JTextField( 20 ); fieldsPanel.add( city ); state = new JTextField( 20 ); fieldsPanel.add( state ); zip = new JTextField( 20 ); fieldsPanel.add( zip ); country = new JTextField( 20 ); fieldsPanel.add( country ); email = new JTextField( 20 ); fieldsPanel.add( email ); home = new JTextField( 20 ); fieldsPanel.add( home ); fax = new JTextField( 20 ); fieldsPanel.add( fax ); setLayout( new GridLayout( 1, 2 ) ); add( labelPanel ); add( fieldsPanel ); } }

44

Acesso a Banco de Dados

package com.targettrust.java.capitulo07; import java.awt.*; import java.awt.event.*; public class ClearFields implements ActionListener { private ScrollingPanel fields; public ClearFields( ScrollingPanel f ) { fields = f; } public void actionPerformed( ActionEvent e ) { fields.id.setText( "" ); fields.first.setText( "" ); fields.last.setText( "" ); fields.address.setText( "" ); fields.city.setText( "" ); fields.state.setText( "" ); fields.zip.setText( "" ); fields.country.setText( "" ); fields.email.setText( "" ); fields.home.setText( "" ); fields.fax.setText( "" ); } }

A classe AddressBook utiliza um objeto ControlPanel e um objeto ScrollingPanel para a GUI do programa. Estabelecemos a conexo de banco de dados passando para getConnection o String URL para JDBC. Classes separadas so definidas para tratar eventos de cada um dos cinco botes na interface com o usurio. A classe AddRecord adiciona um novo registro ao banco de dados em resposta ao boto <Add> na GUI. O construtor do AddRecord) aceita trs argumentos - uma Connection, um ScrollingPanel e uma JTextArea que serve como uma rea de sada para mensagens exibidas por esse programa. No mtodo actionPerformed criamos um objeto Statement para manipular o banco da dados. Testamos se exitem dados nos campos de text. Se esses campos de texto no contiverem dados, nenhum registro ser adicionado ao banco de dados. Construmos a String de SQL INSERT INTO que ser utilizado para adicionar registro ao banco de dados.

45

Acesso a Banco de Dados

46

Acesso a Banco de Dados

Cada nome de coluna a ser atualizado especificado em uma lista separada por vrgulas entre parnteses. O valor para cada coluna especificado depois da palavra-chave VALUES de SQL em outra lista separada por vrgulas entre parnteses. Utilizamos o mtodo Statement executeUpdate para atualizar o banco de dados com o novo registro. O mtodo retorna um int indicando o sucesso ou fracasso da operao de atualizao que testado. Se a atualizao for mal sucedida, todos os campos de texto sero limpos. A classe FindRecord pesquisa no banco de dados um registro especifico em resposta ao boto <Find> na GUI. Testamos. Chamamos o mtodo display e passamos o ResultSet retornado pela chamada a executeQuery. O primeiro registro obtido chamando o mtodo next. Obtemos o nmero de registro do objeto ResultSet rs chamando getInt. Determinamos se o nmero de registro diferente de zero. Se for, os campos de texto sero preenchidos com dados do registro. Exibimos o String do primeiro nome retomado pelo mtodo getString de Resultset, O argumento 2 referencia o nmero de coluna (os nmeros de coluna iniciam a patir de 1) no registro. Instrues semelhantes so executadas para cada campo de texto. Quando essa operao completada, a GUI exibe o primeiro registro do Resultset. A classe UpdateRecord atualiza um registro de banco de dados existente. Criamos a consulta String query de SQL UPDATE. Enviamos a consulta para o banco de dados chamando o mtodo executeUpdate. A classe ClearFields responsvel por limpar os campos de texto em resposta ao boto <Clear> na GUI e a classe Help exibe instrues sobre como utilizar o programa na janela de console na pane inferior da tela.

47

Acesso a Banco de Dados

Processamento de Transaes
Se o banco de dados suporta o processamento de transaes, as alteraes feitas no banco de dados podem ser desfeitas. Java fornece processamento de transaes via mtodos da interface Connection. O mtodo setAutoCommit especifica se cada instruo individual de SQL deve ser realizada e ser comprometida individualmente (um argumento true) ou se vrias instrues de SQL devem ser agrupadas como uma transao (um argumento false). Se o argumento para setAutoCommit for false, o Statement que executa as instrues de SQL deve ser terminado com uma chamada para o mtodo commit de Connection (para comprometer - efetuar - as alteraes no banco de dados) ou mtodo rollback (para retomar o banco de dados para seu estado anterior ao incio da transao). A interface Connection tambm fornece o mtodo getAutoCommit para determinar o estado de autoCommit.

48

Acesso a Banco de Dados

Exerccios
1. Neste captulo vimos como podemos trabalhar com banco de dados em aplicaes java. Agora voc ir implementar na aplicao do curso estas tcnicas estudadas no captulo 07. Primeiro implemente um cdigo que possa validar o usurio e senha da sua tela de login do sistema. Em seguida voc dever implementar classes que permitam salvar os dados da aplicao em um banco de dados. Realize este exerccio de acordo com as instrues do seu instrutor.

49

También podría gustarte