Programação Visual em Java
Short Description
Uma apostila bem interessante sobre programação visual com Java....
Description
Programação JAVA 1. Programação Visual Básica A Interface Gráfica com o Usuário, também conhecido como GUI - Graphical User Interface, em Java, é feita através de bibliotecas de classes, sendo que a primeira a surgir foi a AWT Abstract Window Toolkit). A AWT surgiu já na versão 1.0, mas se tornou confiável a partir da ( Abstract versão 1.1. A maneira como as classes dessa biblioteca trabalham garante a criação dos elementos da interface de usuário seguindo o comportamento destinado às ferramentas GUI nativas de cada plataforma (Windows, Mac, Solaris, ...). Alguns exemplos destes elementos são: botões, listas, menus, componentes de textos, containers (janelas e barras de menus), caixas de diálogo para abrir ou salvar arquivos, além de elementos para manipulação de imagens, fontes e cores. A portabilidade de plataforma funcionava bem em aplicações simples, mas aplicações que envolviam elementos mais complexos, como menus e barras de rolagem, por exemplo, apresentavam diferenças de comportamento conforme a plataforma. O que aconteceu foi que as aplicações visuais feitas em Java não se pareciam, e nem tinham as mesmas funcionalidades, com as aplicações convencionais de cada plataforma. A partir da versão 2 do Java, a JFC (Java Foundation Classes) apresentou novos recursos para a construção da GUI das aplicações, o que melhorou muito os problemas de portabilidade. São eles: •
Java 2D: novas funções para desenhos e gráficos.
•
Drag & Drop: clicar, arrastar, copiar e colar.
•
Swing: biblioteca de classes extensão da AWT, onde são apresentados novos componentes de interface e o que é conhecido por look and feel, que é uma adaptação perfeita da GUI ao sistema operacional específico de desenvolvimento.
É bom salientar que o Swing não substitui o AWT, mas é o kit de ferramentas GUI mais utilizado para desenvolvimento de aplicações visuais. O AWT continua existindo, mantendo a mesma arquitetura criada para o Java versão 1.1. O Swing possui muito mais recursos, além de garantir maior portabilidade e, em boa parte dos casos, é mais fácil de usar. Isso não significa que ou se utiliza AWT ou se utiliza Swing, normalmente o que acontece é que elementos das duas bibliotecas são utilizados conjuntamente nas aplicações. Referente a criação das aplicações, exitem muitas ferramentas que auxiliam na produção de interfaces de usuário gráficas, mas não se comparam a ferramentas para plataformas específicas,
1
como Delphi e VisualBasic, que são voltadas exclusivamente para esse fim. Boa parte da elaboração da interface da aplicação tem que ser feita manualmente, o que exige bastante trabalho.
1.1 Frames Na AWT, a janela de mais alto nível de uma aplicação (não está contida dentro de nenhuma outra) é denominada Frame. No Swing, existe uma versão chamada JFrame, que é derivada/estendida da classe Frame, possuindo alguns poucos métodos adicionais relacionados à manipulação da disposição visual dos frames .Todos os outros métodos são derivados da classe Frame. Um frame pode conter diversos outros componentes da GUI. Para se definir um frame básico baseado em AWT, deve-se: •
Importar o pacote java.awt.*.
•
Estender a classe Frame.
•
Ter um método main() para criar o objeto a partir do operador
•
Torná-lo visível.
new.
Assim, o código a seguir resulta no frame apresentado na figura 1.1. import java.awt.*; public class FrameUm extends Frame { public static void main (String[] args) { FrameUm fr = new FrameUm(); fr.setVisible(true); } }
Para torná-lo visível, é possível utilizar fr.show(); no lugar de fr.setVisible(true);. Percebe-se que não é possível fechá-lo utilizando o botão fechar. Por enquanto, ela deve ser encerrada forçando a finalização do processo (ex.: finalizar tarefa no Windows, ou terminar processo na ferramenta específica de desenvolvimento).
Figura 1.1. Frame FrameUm
O frame criado não possui tamanho definido, nem título ou posicionamento. Para personalizar o frame é necessário inserir um método construtor com as instruções necessárias. Exemplo: import java.awt.*; public class FrameDois extends Frame { public FrameDois() //construtor { setTitle("Frame Dois"); // título do Frame setSize(300, 200); // largura: 300 pixels altura: 200 pixels setResizable(false); // não permite o redimensionamento
2
como Delphi e VisualBasic, que são voltadas exclusivamente para esse fim. Boa parte da elaboração da interface da aplicação tem que ser feita manualmente, o que exige bastante trabalho.
1.1 Frames Na AWT, a janela de mais alto nível de uma aplicação (não está contida dentro de nenhuma outra) é denominada Frame. No Swing, existe uma versão chamada JFrame, que é derivada/estendida da classe Frame, possuindo alguns poucos métodos adicionais relacionados à manipulação da disposição visual dos frames .Todos os outros métodos são derivados da classe Frame. Um frame pode conter diversos outros componentes da GUI. Para se definir um frame básico baseado em AWT, deve-se: •
Importar o pacote java.awt.*.
•
Estender a classe Frame.
•
Ter um método main() para criar o objeto a partir do operador
•
Torná-lo visível.
new.
Assim, o código a seguir resulta no frame apresentado na figura 1.1. import java.awt.*; public class FrameUm extends Frame { public static void main (String[] args) { FrameUm fr = new FrameUm(); fr.setVisible(true); } }
Para torná-lo visível, é possível utilizar fr.show(); no lugar de fr.setVisible(true);. Percebe-se que não é possível fechá-lo utilizando o botão fechar. Por enquanto, ela deve ser encerrada forçando a finalização do processo (ex.: finalizar tarefa no Windows, ou terminar processo na ferramenta específica de desenvolvimento).
Figura 1.1. Frame FrameUm
O frame criado não possui tamanho definido, nem título ou posicionamento. Para personalizar o frame é necessário inserir um método construtor com as instruções necessárias. Exemplo: import java.awt.*; public class FrameDois extends Frame { public FrameDois() //construtor { setTitle("Frame Dois"); // título do Frame setSize(300, 200); // largura: 300 pixels altura: 200 pixels setResizable(false); // não permite o redimensionamento
2
setLocation(200, 100); // x: 200 pixels } public static void main (String[] args) { FrameDois fr = new FrameDois(); fr.setVisible(true); }
y: 100 pixels
}
A figura 1.2 mostra o resultado da execução, um frame com largura 300 x 200 pixels (setSize()), com o título “Frame Dois” ( setTitle()), que não permite redimensionamento (setResizable()).
Figura 1.2. Frame FrameDois
Além disso, o setLocation() realiza o posicionamento em tela do frame, seguindo o sistema de coordenadas do Java (figura 1.3), medidas em pixels, conforme a resolução atual da tela. No exemplo, o frame fica posicionado em 200 200 pixels para x e 100 pixels para y. x
(0 ,0)
(x, y)
y
Figura 1.3. Sistema de coordenadas do Java
Conforme já mencionado, o frame ainda não pode ser fechado. Para que isso aconteça é necessário ter uma maneira de se ter a notificação de quando ele é fechado. A partir da manipulação desse evento, mostrado no exemplo a seguir, é possível fechar o frame. É necessário importar o pacote java.awt.event.* para manipular eventos do AWT. O modelo de eventos e os demais eventos de janela serão vistos em seções posteriores. import java.awt.*;
3
import java.awt.event.*; public class FrameTres extends Frame { public FrameTres() //construtor { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setTitle("Frame Três"); // título do Frame setSize(300, 200); // largura: 300 pixels altura: 200 pixels setResizable(false); // não permite o redimensionamento setLocation(200, 100); // x: 200 pixels y: 100 pixels } public static void main (String[] args) { FrameTres fr = new FrameTres(); fr.setVisible(true); } }
Ainda em relação ao posicionamento, dependendo da resolução da tela onde o frame será aberto, pode se ter situações bem desagradáveis, como, por exemplo, o frame ser aberto e ficar com parte fora da tela. É necessário então posicionar o frame em coordenadas que independam da resolução utilizada. O exemplo a seguir abrirá um frame com a metade do tamanho da tela, posicionado no centro, respeitando a resolução. import java.awt.*; import java.awt.event.*; public class FrameQuatro extends Frame { public FrameQuatro() //construtor { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); Toolkit tk = Toolkit.getDefaultToolkit(); Dimension d = tk.getScreenSize(); setSize(d.width / 2, d.height / 2); setLocation(d.width / 4, d.height / 4); Image img = tk.getImage("icone.gif"); setIconImage(img); setTitle("Frame Quatro"); setResizable(false); } public static void main (String[] args) { FrameQuatro fr = new FrameQuatro(); fr.setVisible(true); } }
Para que seja possível essa tarefa de posicionamento conforme a resolução de vídeo, é necessário obter informações do sistema operacional, e isso é feito através da classe Toolkit, método getScreenSize(), cujos dados são jogados em um objeto da classe Dimension , que armazena a altura e largura nos campos d.width e d.height. Por exemplo, se a resolução de vídeo for 800x600, o d.width fica com 800 e o d.height fica com 600. Tendo esses valores, é possível utilizar em métodos como o setLocation() e o setSize(), como foi feito no exemplo. Além disso, o exemplo também acrescenta um ícone ao frame, também utilizando a classe Toolkit, 4
método getImage(), para carregar a imagem (extensão .gif) e jogar em um objeto da classe Image, para depois setar o ícone através do setIconImage(). O mesmo exemplo pode ser feito baseado na biblioteca Swing, classe derivação e importando o pacote javax.swing.*, assim: import import import public { ... }
JFrame,
mudando apenas a
java.awt.*; java.awt.event.*; javax.swing.*; class FrameQuatro extends JFrame
Os exemplos apresentados nas próximas seções criarão frames baseado na classe
JFrame.
1.2 Mostrando Textos e Linhas no Frame Para que seja possível mostrar textos em um frame é necessário criar um objeto baseado na classe Graphics, que será responsável pelo gerenciamento da área gráfica a ser desenhada, controlando cores, tipos de fontes, etc. A classe Component possui um método paint() que aceita um objeto Graphics como parâmetro. Esse método, na classe de origem, não faz nada, por isso ele deve ser sobrescrito com a chamada de métodos que realizam operações de escrita, pintura, desenho, etc. Para efetuar a sobreposição do método paint() deve-se ter o cabeçalho: public void paint(Graphics g)
A partir disso, métodos como drawString() e drawLine() podem ser utilizados, como no exemplo a seguir. O resultado é apresentado na figura 1.4. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MostrandoTextos extends JFrame { public MostrandoTextos() { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); Toolkit tk = Toolkit.getDefaultToolkit(); Dimension d = tk.getScreenSize(); int screenHeight = d.height; int screenWidth = d.width; setSize(d.width / 2, d.height / 2); setLocation(d.width / 4, d.height / 4); setTitle("Escrevendo Textos"); setResizable(false); } public void paint (Graphics g) { g.drawString("Estou escrevendo no frame", 40, 50); g.drawLine(40, 60, 200, 60); int i = 30; while (i < 150) {
5
g.drawString("Estou escrevendo no frame", 40+i, 50+i); g.drawLine(40+i, 60+i, 200+i, 60+i); i+=30; } } public static void main (String[] args) { MostrandoTextos fr = new MostrandoTextos(); fr.setVisible(true); } }
Figura 1.4. Frame MostrandoTextos
O método drawString(String s, int x, int y) realiza a mostragem de um texto em uma posição definida por x e y. O método drawLine(int x1, int y1, int x2, int y2) desenha uma linha que inicia nas coordenadas x1,y1 e termina nas coordenadas x2,y2.
1.3 Cores O método setColor() seleciona a cor que é utilizada para todas as operações de desenho dentro do contexto gráfico ou componente. Um parâmetro Color define a cor a ser usada, sendo que as treze cores padrão, apresentadas na tabela 1.1, estão definidas na classe java.awt.Color. black
(preto)
magenta
blue
(azulo)
orange
cyan
(ciano)
pink
darkGray gray
(cinza-escuro)
(cinza)
green
(verde)
red
(magenta)
(laranja)
(rosa)
(vermelho)
white
(branco)
yellow
(amarelo)
6
lightGray
(cinza-claro)
Tabela 1.1. Cores definidas em java.awt.Color
Além das cores pré-definidas, pode-se criar novas cores baseadas no conteúdo RGB (redvermelho, green-verde, blue-azul), expressos por inteiros de 0 a 255. O exemplo a seguir apresenta a criação de objetos coloridos em um frame. O resultado é apresentado na figura 1.5. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Cores extends JFrame { public Cores() { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400, 200); setLocation(200, 100); setTitle("Cores"); } public void paint (Graphics g) { g.setColor(Color.blue); g.drawString("Cor Azul", 50, 50); g.setColor(Color.green); g.drawLine(50, 60, 220, 60); g.setColor(Color.red); g.drawRect(50,70,100,30); g.setColor(new Color(0,128,128)); g.fillRect(50,110,100,30); } public static void main (String[] args) { Cores fr = new Cores(); fr.setVisible(true); } }
Figura 1.5. Frame Cores
7
O método drawRect(int x, int y, int width, int height) desenha um retângulo com a cor definida em setColor(), iniciando nas coordenadas x,y, tendo uma largura width e uma altura height. O método fillRect(int x, int y, int width, int height) faz a mesma coisa, mas preenche o retângulo.
1.4 Fontes O método responsável por definir o tipo de fonte desejado é o setFont(), que precisa de um objeto criado, baseado na classe Font, definindo assim o nome da fonte, o seu estilo e seu tamanho. O nome pode ser qualquer fonte suportada pelo sistema operacional específico; o estilo pode ser: PLAIN – regular, BOLD – negrito e ITALIC – itálico, sendo possível combinar os estilos utilizando o operador +; o tamanho pode ser qualquer valor que represente o tamanho em pontos da fonte. Exemplo: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Fontes extends JFrame { public Fontes() { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,130); setTitle("Tipos de Fonte"); } public void paint (Graphics g) { g.setColor(Color.blue); Font f = new Font("SansSerif", Font.ITALIC, 16); g.setFont(f); g.drawString("Fonte SansSerif itálico tamanho 16", 20, 50); g.setFont(new Font("Monospaced", Font.BOLD + Font.ITALIC, 14)); g.drawString("Fonte Monospaced negrito e itálico tamanho 14", 20, 80); g.setFont(f); g.drawString("Novamente Fonte SansSerif itálico tamanho 16", 20, 110); } public static void main (String[] args) { Fontes fr = new Fontes(); fr.setVisible(true); } }
A figura 1.6 mostra o resultado. Percebe-se que não é necessário criar explicitamente um objeto do tipo Font (objeto f), podendo ser possível criá-lo no próprio argumento do setFont(). Se a fonte for utilizada várias vezes no decorrer da aplicação, torna-se útil a criação do objeto explicitamente.
8
Figura 1.6. Frame Fontes
Em termos de portabilidade, deve-se tomar cuidado quanto a fontes que não existem em alguns sistemas operacionais. O ideal é trabalhar com fontes comuns em sistemas operacionais diferentes. O modelo do AWT define cinco fontes disponíveis em qualquer sistema operacional. São elas: Serif, Monospaced, SansSerif, Dialog e DialogInput.
1.5 Outras Formas Geométricas Além das formas já apresentadas, existem várias outras possíveis, a maioria com a opção de preenchimento ou não, a partir da precedência de draw ou fill. O exemplo a seguir tem como resultado o frame apresentado na figura 1.7. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class FormasGeometricas extends JFrame { public FormasGeometricas() { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(460,140); setTitle("Formas Geométricas"); } public void paint (Graphics g) { g.setColor(Color.red); g.drawRoundRect(10,30,80,40,30,30); g.fillRoundRect(10,80,80,40,30,30); g.setColor(Color.yellow); g.draw3DRect(100,30,80,40,true); g.fill3DRect(100,80,80,40,false); g.setColor(Color.blue); g.drawOval(190,30,80,40); g.fillOval(190,80,80,40); g.setColor(Color.darkGray); g.drawArc(280,30,80,40,90,270); g.fillArc(280,80,80,40,90,270); g.setColor(Color.magenta); int ValoresX[] = {370,450,410,370}; int ValoresY[] = {30,30,70,30}; g.drawPolygon(ValoresX,ValoresY,3); int ValoresX2[] = {370,450,410,370}; int ValoresY2[] = {80,80,120,80}; g.fillPolygon(ValoresX2,ValoresY2,3);
9
} public static void main (String[] args) { FormasGeometricas fr = new FormasGeometricas(); fr.setVisible(true); } }
Figura 1.7. Frame Fontes
Várias formas geométricas foram desenhadas no frame. Funcionamento de cada método: •
drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight): Desenha um retângulo com cantos arredondados, iniciando nas coordenadas x,y, tendo uma largura width e uma altura height, e cantos definidos por arcWidth e arcHeight.
•
fillRoundRect(int x, int y, int width, int height, arcHeight): Idem a drawRoundRect, mas preenche o retângulo.
•
•
•
int
draw3DRect(int x, int y, int width, int height, boolean raised): Desenha um retângulo 3D, iniciando nas coordenadas x,y, tendo uma largura width e uma altura height, e um valor lógico para indicar a aparência do 3D. fill3DRect(int x, int y, int width, int height, boolean raised): draw3DRect, mas preenche o retângulo. drawOval(int x,
int y,
fillOval(int x, int y, int width, int height):
a forma oval.
Idem a
int height): Desenha uma forma inicia em x,y, tendo uma largura width
int width,
baseado nas coordenadas do retângulo que altura height. •
int arcWidth,
oval, e uma
Idem a drawOval, mas preenche
•
drawArc(int x, int y, int width, int height, int startAngle, int arcAngle): Desenha um arco, baseado nas coordenadas do retângulo que inicia em x,y, tendo uma largura width e uma altura height, mostrando apenas a linha que vai do ângulo startAngle até o ângulo arcAngle.
•
fillArc(int x, arcAngle): Idem
a
int y, int width, int height, drawArc, mas preenche o arco.
int startAngle,
int
10
•
drawPolygon(int[] xPoints,
polígono, baseado nas coordenadas •
int[] yPoints, dos arranjos x,y.
fillPolygon(int[] xPoints, int[] yPoints, drawPolygon, mas preenche o arco.
int nPoints):
Desenha
um
Idem
a
int nPoints):
1.6 Imagens A classe Image é a responsável pelo carregamento de imagens armazenadas em disco. Novamente, é necessário utilizar um objeto do tipo Toolkit para obter uma imagem, através do método getImage(), e depois jogar em um objeto do tipo Image. O exemplo a seguir mostra a maneira de se preencher um frame com as imagens lado a lado. A figura 1.8 mostra o resultado. import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Imagens extends JFrame { public Imagens() //construtora { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,200); setTitle("Imagens"); } public void paint (Graphics g) { Image ima = Toolkit.getDefaultToolkit().getImage("LogoJava.gif"); int larguraTela = 400; int alturaTela = 200; int larguraImagem = ima.getWidth(this); int alturaImagem = ima.getHeight(this); g.drawImage(ima,4,23,null); for (int i = 0; i = 0; i--) dtm.removeRow(linhas[i]); } if (origem == btnMostrar) { if (tabela.getSelectedRow()>=0) texto.setText(tabela.getValueAt (tabela.getSelectedRow(),1).toString()); } } public static void main(String args[]) { TabelaFormaDois fr = new TabelaFormaDois(); fr.setVisible(true); } }
Figura 3.27. Uma tabela baseada no DefaultTableModel
A figura 3.26 apresenta o resultado da execução após clicar em alguns botões. A tabela foi criada normalmente, baseada no JTable. Após isso, foi setado o modelo pelo método setModel(), cujo parâmetro é a criação de um objeto DefaultTableModel, iniciando com um arranjo bidimensional vazio e um arranjo String com os nomes das colunas. Nenhum dado é apresentado inicialmente porque isso é uma tarefa do botão Incluir. Para cada coluna foi configurado o seu tamanho, a partir do método setPreferredWidth() e se é redimensinável ou não, a partir do método setResizable(). A coluna Ativo é diferente das demais, pois apresenta um caixa de seleção. Para que isso seja possível, foi definido um objeto cbAtivo, do tipo JComboBox, que, posteriormente, foi inserido na tabela a partir do método setCellEditor(). As
colunas
deixaram
de ser passíveis de reorganização a partir do método setReorderingAllowed(), setado para false. O método setAutoResizeMode() configura o modo de redimensionamento automático das colunas da tabela, sendo que o AUTO_RESIZE_OFF desliga esse redimensionamento. Os outros modos existentes são: 89
•
AUTO_RESIZE_NEXT_COLUMN :
redimensiona apenas a próxima coluna.
•
AUTO_RESIZE_SUBSEQUENT_COLUMNS:
redimensiona todas as colunas subseqüentes, sendo
o padrão. •
AUTO_RESIZE_LAST_COLUMN :
redimensiona apenas a última coluna.
•
AUTO_RESIZE_ALL_COLUMNS :
redimensiona todas as colunas da tabela.
Após, a tabela é inserida em um JScrollPane, para perimitir a existência de barras de rolagem, e este, por fim, é inserido no contêiner. O painel de baixo contém três botões e uma caixa de texto. O primeiro botão, Incluir, ao ser clicado, utiliza o método getModel() para criar o objeto dtm, do tipo DefaultTableModel. Tal objeto possui o método addRow(), que é usado para inserir uma linha na tabela, sempre com os mesmos campos, apenas mudando a numeração, controlada pela variável inteira incCod. O segundo botão, Excluir, também cria um objeto dtm, além de utilizar o getSelectedRows() para alimentar o arranjo int linhas com as linhas selecionadas. Um for percorrendo as linhas selecionadas foi feito para excluí-las a partir do método removeRow(). Por fim, o terceiro botão, Mostrar, mostra na caixa de texto o conteúdo da célula 1 ( Nome) da linha selecionada (getSelectedRow()). Isso é capturado a partir do método getValueAt().
3.13.2 Modelo AbstractTableModel A classe DefaultTableModel é uma classe com métodos básicos para trabalhar com os dados da JTable. Uma opção mais avançada é criar uma classe própria, estendendo a classe AbstractTableModel, que fornece diversos métodos prontos, exceto: •
public Object getValueAt(int row, int col): determinado por row e col.
•
public int getRowCount():
•
public int getColumnCount():
retorna o objeto contido na célula
retorna o número de linhas da tabela. retorna o número de colunas da tabela.
A classe criada é o próprio modelo da tabela e os métodos apresentados devem ser implementados, obrigatoriamente. Muitos outros métodos existem, e eles podem ser sobrepostos para realizar as ações desejadas para a tabela específica. Por exemplo, o método getColumnName() atribuirá os nomes A, B, C, etc. aos nomes das colunas, a não ser que ele seja sobreposto para que atribua nomes significativos. Assim, é necessário sobrepor os métodos existentes na classe AbstractTableModel da melhor forma possível, para que atenda às necessidades do modelo específico da tabela que será implementada. Na verdade, uma vez tendo o modelo bem elaborado, é possível utiliza-lo na criação de várias tabelas. O código a seguir implementa várias sobreposições de métodos para exemplificar a criação de um modelo e de uma tabela baseada nesse modelo. import javax.swing.*; import javax.swing.table.*;
90
import java.awt.*; import java.awt.event.*; import java.util.*; public class TabelaFormaTres extends JFrame implements ActionListener { private JButton btnExcluir; private JButton btnIncluir; private JButton btnMostrar; private JButton btnAlterar; private JButton btnMostrarClasse; private JTextField texto; private JTable tabela; private int incCod = 0; private ModeloTabela modelo; public TabelaFormaTres() { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setTitle("Tabela - Forma Três"); setSize(600,250); setLocation(100,50); Container P = getContentPane(); P.setLayout(new BorderLayout()); // criação de um arranjo sem tamanho definido para inserção // dinâmica de objetos ArrayList dados = new ArrayList(); // criação de um arranjo para os títulos no cabeçalho String[] colunas = new String[] { "ID", "Nome", "Sobrenome", "Limite", "Ativo" }; // criação de um arranjo para identificar se a célula é editável ou não boolean[] edicao = {false, true, true, false, true}; // Inserção da primeira linha da tabela dados.add(new Object[]{ new Integer(++incCod), "Cliente " + incCod, "Endereço " + incCod, new Double(999.99), new Boolean(true) }); // criação da tabela baseada no modelo ModeloTabela modelo = new ModeloTabela(dados, colunas, edicao); tabela = new JTable(modelo); tabela.getColumnModel().getColumn(0).setPreferredWidth(50); tabela.getColumnModel().getColumn(0).setResizable(false); tabela.getColumnModel().getColumn(1).setPreferredWidth(200); tabela.getColumnModel().getColumn(1).setResizable(true); tabela.getColumnModel().getColumn(2).setPreferredWidth(200); tabela.getColumnModel().getColumn(2).setResizable(true); tabela.getColumnModel().getColumn(3).setPreferredWidth(80); tabela.getColumnModel().getColumn(3).setResizable(true); tabela.getColumnModel().getColumn(4).setPreferredWidth(55); tabela.getColumnModel().getColumn(4).setResizable(true); tabela.getTableHeader().setReorderingAllowed(false); tabela.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tabela.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
91
JScrollPane rolagemTabela = new JScrollPane(tabela); P.add(rolagemTabela,"Center"); // criação do Painel de baixo JPanel PTabSul = new JPanel(); btnIncluir = new JButton("Incluir"); PTabSul.add(btnIncluir); btnExcluir = new JButton("Excluir"); PTabSul.add(btnExcluir); btnMostrar = new JButton("Mostrar"); PTabSul.add(btnMostrar); btnAlterar = new JButton("Alterar"); PTabSul.add(btnAlterar); btnMostrarClasse = new JButton("Classe"); PTabSul.add(btnMostrarClasse); texto = new JTextField(15); PTabSul.add(texto); P.add(PTabSul, "South"); btnExcluir.addActionListener(this); btnIncluir.addActionListener(this); btnMostrar.addActionListener(this); btnAlterar.addActionListener(this); btnMostrarClasse.addActionListener(this); } public void actionPerformed(ActionEvent evt) { Object origem = evt.getSource(); if (origem == btnIncluir) { modelo.addRow(new Object[]{ new Integer(++incCod), "Cliente " + incCod, "Endereço " + incCod, new Double(999.99), new Boolean(true) }); } if (origem == btnExcluir) { modelo.removeRow(tabela.getSelectedRow()); } if (origem == btnMostrar) { if (tabela.getSelectedRow()>=0) texto.setText(modelo.getValueAt(tabela.getSelectedRow(), tabela.getSelectedColumn()).toString()); } if (origem == btnAlterar) { if (tabela.getSelectedRow()>=0) modelo.setValueAt(texto.getText(),tabela.getSelectedRow(), tabela.getSelectedColumn()); } if (origem == btnMostrarClasse) { if (tabela.getSelectedRow()>=0) texto.setText(modelo.getColumnClass(
92
tabela.getSelectedColumn()).toString()); } } public static void main(String args[]) { TabelaFormaTres fr = new TabelaFormaTres(); fr.setVisible(true); } } class ModeloTabela extends AbstractTableModel { private ArrayList linhas = null; private String[] colunas = null; private boolean[] colEditavel; public ModeloTabela(ArrayList lin, String[] col, boolean[] editavel) { setLinhas(lin); setColunas(col); colEditavel = editavel; } public ArrayList getLinhas() { return linhas; } public void setLinhas(ArrayList dados) { linhas = dados; } public String[] getColunas() { return colunas; } public void setColunas(String[] nomes) { colunas = nomes; } public int getColumnCount() { return colunas.length; } public int getRowCount() { return linhas.size(); } public String getColumnName(int numCol) { return colunas[numCol];
93
} public boolean isCellEditable(int numCol) { return colEditavel[numCol]; } public Object getValueAt(int numLin, int numCol) { Object[] linha = (Object[])getLinhas().get(numLin); return linha[numCol]; } public void setValueAt(Object dado, int numLin, int numCol) { if (isCellEditable(numCol)) { Object[] linha = (Object[])getLinhas().get(numLin); linha[numCol] = dado; fireTableDataChanged(); } } public void addRow(Object[] dados) { getLinhas().add(dados); fireTableDataChanged(); } public void removeRow(int numLin) { getLinhas().remove(numLin); fireTableDataChanged(); } public Class getColumnClass(int numCol) { Object[] linha = (Object[])getLinhas().get(0); return linha[numCol].getClass(); } }
94
Figura 3.28. Uma tabela baseada no modelo criado a partir do AbstractTableModel
Antes de tudo, é importante entender a classe ModeloTabela, que é derivada de AbstractTableModel. O conteúdo das linhas é armazenado em um objeto linhas, do tipo ArrayList. Um ArrayList permite armazenar qualquer tipo de objeto de uma forma dinâmica, ou seja, não é necessário determinar o tamanho dele na sua declaração. Assim, será possível inserir ou excluir linhas a qualquer momento. Dois outros arranjos são criados: colunas, do tipo String, que armazena o nome das colunas, a ser mostrado no cabeçalho da tabela e; colEditavel, do tipo boolean, que armazena true ou false, conforme a coluna possa ser editável ou não. Os primeiros quatro métodos realizam o tratamento dos dados dos arranjos linhas e colunas. São eles: •
public void setLinhas(ArrayList dados):
•
public ArrayList getLinhas():
•
public void setColunas(String[] nomes):
•
public String[] getColunas():
alimenta o arranjo das linhas
retorna o arranjo das linhas. alimenta o arranjo das colunas.
retorna o arranjo das colunas.
O contrutor da classe recebe três parâmetros: um ArrayList, para iniciar a tabela com as linhas desejadas; um arranjo String, que são os nomes das colunas, e; um arranjo boolean, com a indicação da possibilidade de edição de cada uma das colunas. No momento da instanciação em alguma aplicação, esses dados devem ser passados para que a tabela tenha uma situação inicial. Como explicado anteriormente, os nomes das colunas não seriam atribuídos se não fosse sobreposto o método getColumnName(), que retorna exatamente o conteúdo atribuído ao arranjo colunas. Além disso, os dois métodos obrigatórios getRowCount()e getColumnCount() são implementados, retornando o número de linhas e colunas do modelo. Os demais métodos implementados são:
95
•
•
•
public boolean isCellEditable(int numCol): editável, e false, caso contrário.
retorna true se a coluna numCol for
public Object getValueAt(int numLin, int numCol): Implementação Obtém o valor contido na célula de coordenadas numLin, numCol.
obrigatória.
public void setValueAt(Object dado, int numLin, int numCol): define um novo valor para a célula de coordenadas numLin, numCol, se esta for editável (testado a partir do método isCellEditable()). Percebe-se que, após inserido o objeto na célula, é invocado o método fireTableDataChanged(), que tem a função de realizar a efetiva
alteração dos dados da tabela. •
public void addRow(Object[] dados):
arranjo de objetos. •
•
public void removeRow(int numLin):
inclui uma linha na tabela a partir de um
exclui a linha numLin da tabela.
public Class getColumnClass(int numCol): coluna numCol.
retorna a classe do objeto contido na
A criação da tabela baseada nesse modelo, que resulta na aplicação mostrada na figura 3.28, é feita na classe TabelaFormaTres. O ArrayList dados é criado e é adicionado a ele apenas uma única linha, que é um arranjo de vários objetos de tipos diferentes. Além de dados, o arranjo colunas é criado e alimentado com os nomes das colunas da tabela; e o arranjo edicao é criado com a indicação se cada coluna é editável ou não. Tais arranjos são passados como parâmetro na criação do objeto da classe ModeloTabela, explicado anteriormente, chamado modelo, e este serve como parâmetro na criação da JTable. Após, como no exemplo anterior, são definidos os tamanhos de cada coluna (setPreferredWidth()), e se elas são redimensionáveis ou não ( setResizable()). Também igualmente ao exemplo anterior, as colunas deixam de ser reorganizáveis, a partir do método setReorderingAllowed(), setado para false, e é configurado o modo de redimensionamento automático das colunas da tabela, a partir do método setAutoResizeMode(). Adicionalmente, o setSelectionMode() determina que só é possível selecionar uma linha por vez (SINGLE_SELECTION). Os outros dois valores possíveis são: MULTIPLE_INTERVAL_SELECTION, que permite a seleção de uma ou mais linhas, de forma contígua ou não, e; SINGLE_INTERVAL_SELECTION , que permite a seleção de uma ou mais linhas, desde que seja de forma contígua. A tabela criada é, então, jogada em um JScrollPane e esse no contêiner. Após, os botões Incluir, Excluir, Mostrar, Alterar e Classe são inseridos, além do JTextField texto. As ações desses botões foram implementadas no ActionPerformed: •
Incluir:
tabela.
utiliza o método
addRow()
do modelo para incluir uma nova linha no final da
96
•
•
•
•
Excluir:
utiliza o método removeRow() do modelo para excluir a linha que está selecionada, capturada a partir do método getSelectedRow(). Mostrar:
mostra o conteúdo da célula no campo texto, caso haja uma linha selecionada. Isso é feito pelo método getValueAt(), passando como parâmetro o número da linha (getSelectedRow()) e coluna (getSelectedColumn() ) referente à célula selecionada. Alterar:
Se houver linha selecionada, o conteúdo da célula selecionada é alterado pelo valor contido no campo texto, a partir do método setValueAt(). Classe:
utiliza o método getSelectedColumn() para capturar a classe da célula selecionada, mostrando no campo texto.
3. Banco de Dados: Conectividade Utilizando JDBC A pa import import import import import import
javax.swing.*; java.awt.*; java.awt.event.*; java.util.*; java.sql.*; javax.swing.border.*;
public class CriaTabelas extends JFrame implements ActionListener { private JButton btnExcluir; private JButton btnIncluir; private JButton btnLimpar; private JButton btnConectar; private JButton btnDesconectar; private JButton btnCriar; private JTextField nomeCampo; private JTextField tipoCampo; private JTextField fonteDados; private JTextField usuario; private JPasswordField senha; private JTextField nomeTabela; private JList lista; private Vector campos; private JLabel lblCon; private Connection con; private String chavePrimaria; public CriaTabelas() { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setTitle("Wizard para criação de tabelas de BD"); setSize(500,320); setLocation(100,100); Container P = getContentPane(); P.setLayout(new BorderLayout()); campos = new Vector();
97
// criação do primeiro painel JPanel PNorte = new JPanel(); PNorte.setLayout(new BorderLayout()); JPanel PNorteNorte = new JPanel(); PNorteNorte.add(new JLabel("Fonte de Dados")); fonteDados = new JTextField(13); PNorteNorte.add(fonteDados); PNorteNorte.add(new JLabel("Usuário")); usuario = new JTextField(7); PNorteNorte.add(usuario); PNorteNorte.add(new JLabel("Senha")); senha = new JPasswordField(5); PNorteNorte.add(senha); PNorte.add(PNorteNorte,"North"); JPanel PNorteCentro = new JPanel(); btnConectar = new JButton("Conectar Banco"); btnConectar.addActionListener(this); PNorteCentro.add(btnConectar); lblCon = new JLabel("Não Conectado"); PNorteCentro.add(lblCon); btnDesconectar = new JButton("Desconectar Banco"); btnDesconectar.addActionListener(this); PNorteCentro.add(btnDesconectar); PNorte.add(PNorteCentro,"Center"); P.add(PNorte, "North"); // criação do segundo painel JPanel PCentro = new JPanel(); PCentro.add(new JLabel("Nome da Tabela")); nomeTabela = new JTextField(10); PCentro.add(nomeTabela); lista = new JList(); lista.setVisibleRowCount(8); lista.setFixedCellWidth(200); lista.setFixedCellHeight(15); lista.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); PCentro.add(new JScrollPane(lista)); btnCriar = new JButton("Criar Tabela"); btnCriar.addActionListener(this); PCentro.add(btnCriar); btnLimpar = new JButton("Limpar lista"); btnLimpar.addActionListener(this); PCentro.add(btnLimpar); Border borda = BorderFactory.createEtchedBorder(); PCentro.setBorder(borda); P.add(PCentro, "Center"); // criação do terceiro painel JPanel PSul = new JPanel(); PSul.add(new JLabel("Nome")); nomeCampo = new JTextField(10); PSul.add(nomeCampo); PSul.add(new JLabel("Tipo")); tipoCampo = new JTextField(10); PSul.add(tipoCampo); btnIncluir = new JButton("Incluir"); PSul.add(btnIncluir); btnExcluir = new JButton("Excluir"); PSul.add(btnExcluir);
98
P.add(PSul, "South"); btnExcluir.addActionListener(this); btnIncluir.addActionListener(this); } public void actionPerformed(ActionEvent evt) { Object origem = evt.getSource(); if (origem == btnConectar) { String sFonte = "jdbc:odbc:" + fonteDados.getText().trim(); String sUsuario = usuario.getText().trim(); String sSenha = senha.getText().trim(); try { System.setProperty("jdbc.drivers","sun.jdbc.odbc.JdbcOdbcDriver"); con = DriverManager.getConnection(sFonte, sUsuario, sSenha); JOptionPane.showMessageDialog(this, "Banco conectado com sucesso!", "Mensagem", JOptionPane.WARNING_MESSAGE); lblCon.setText("Conectado"); }catch (SQLException eSQL) { // exceções de SQL eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Falha na conexão com o banco!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); }catch (Exception e) { // demais exceções e.printStackTrace(); JOptionPane.showMessageDialog(this, "Falha na conexão com o banco!\n" + "Mensagem: " + e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } } if (origem == btnDesconectar) { try { con.close(); lblCon.setText("Desconectado"); }catch (SQLException eSQL) { // exceções de SQL eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Não foi possível desconectar o banco!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } } if (origem == btnIncluir) { String item = nomeCampo.getText() + " " + tipoCampo.getText(); if (campos.isEmpty()) { JOptionPane.showMessageDialog(this, "O primeiro campo será a chave primária da tabela",
99
"Mensagem", JOptionPane.WARNING_MESSAGE); chavePrimaria = nomeCampo.getText(); } campos.addElement(item); lista.setListData(campos); } if (origem == btnExcluir) { if (lista.getSelectedIndex()>= 0) { campos.removeElementAt(lista.getSelectedIndex()); lista.setListData(campos); } } if (origem == btnLimpar) { campos.removeAllElements(); lista.setListData(campos); } if (origem == btnCriar) { String itens = campos.toString(); itens = itens.substring(1,itens.length()-1); String sentencaSQL = "CREATE TABLE " + nomeTabela.getText().trim() + " (" + itens + ", PRIMARY KEY (" + chavePrimaria + "))" ; try{ Statement st = con.createStatement(); st.executeUpdate(sentencaSQL); JOptionPane.showMessageDialog(this, "Tabela criada com sucesso!", "Mensagem", JOptionPane.WARNING_MESSAGE); }catch (SQLException eSQL) { eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Não foi possível criar a tabela!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } } } public static void main(String args[]) { CriaTabelas fr = new CriaTabelas(); fr.setVisible(true); } }
100
A import import import import import import
javax.swing.*; java.awt.*; java.awt.event.*; java.sql.*; java.util.*; javax.swing.table.*;
public class Consulta extends JFrame implements ActionListener { private JButton btnSair; private JButton btnPesqNome; private JButton btnPesqCod; private JTextField nome; private JTextField codigo; private Connection con; private ModeloTabelaBD modelo; private JTable tabela; private Statement sentenca; private ResultSet registros; public Consulta() { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setTitle("Consulta a Banco de Dados"); setSize(500,320); setLocation(100,100); Container P = getContentPane(); P.setLayout(new BorderLayout()); // conecta o banco con = conectaBanco("jdbc:odbc:ODBCBancoExemplo", null, null); // criação do primeiro painel JPanel PNorte = new JPanel();
101
PNorte.setLayout(new BorderLayout()); JPanel PNorteNorte = new JPanel(); PNorteNorte.add(new JLabel("Digite nome")); nome = new JTextField(13); PNorteNorte.add(nome); btnPesqNome = new JButton("Pesquisar por nome"); PNorteNorte.add(btnPesqNome); btnPesqNome.addActionListener(this); PNorte.add(PNorteNorte,"North"); JPanel PNorteCentro = new JPanel(); PNorteCentro.add(new JLabel("Digite código")); codigo = new JTextField(7); PNorteCentro.add(codigo); btnPesqCod = new JButton("Pesquisar por código"); PNorteCentro.add(btnPesqCod); PNorte.add(PNorteCentro,"Center"); btnPesqCod.addActionListener(this); P.add(PNorte, "North"); // criação da tabela // criação de um array para inserção dinâmica de objetos ArrayList dados = new ArrayList(); // criação de um array para os títulos no cabeçalho String[] colunas = new String[] { "Código", "Nome", "Endereço"}; // criação de um array para identificar se a célula é editável ou não boolean[] edicao = {false, false, false}; // seleciona todos os registros da tabela Clientes e joga no ArrayList try { String sentencaSQL = "SELECT * FROM Clientes ORDER BY Codigo"; sentenca = con.createStatement(); registros = sentenca.executeQuery(sentencaSQL); boolean proximoRegistro = registros.next(); if (!proximoRegistro) { JOptionPane.showMessageDialog(this, "Nenhum registro foi encontrado!", "Mensagem", JOptionPane.WARNING_MESSAGE); } else do { dados.add(new Object[]{ new Integer(Integer.parseInt(registros.getString("Codigo"))), registros.getString("Nome"), registros.getString("Endereco") }); } while (registros.next()); sentenca.close(); }catch (SQLException eSQL) { eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Não foi possível carregar os dados!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } // criação da tabela baseada no modelo ModeloTabelaBD modelo = new ModeloTabelaBD(dados, colunas, edicao); tabela = new JTable(modelo); tabela.getColumnModel().getColumn(0).setPreferredWidth(50);
102
tabela.getColumnModel().getColumn(0).setResizable(false); tabela.getColumnModel().getColumn(1).setPreferredWidth(200); tabela.getColumnModel().getColumn(1).setResizable(true); tabela.getColumnModel().getColumn(2).setPreferredWidth(240); tabela.getColumnModel().getColumn(2).setResizable(true); tabela.getTableHeader().setReorderingAllowed(false); tabela.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tabela.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane rolagemTabela = new JScrollPane(tabela); P.add(rolagemTabela, "Center"); // criação do terceiro painel JPanel PSul = new JPanel(); btnSair = new JButton("Sair"); PSul.add(btnSair); P.add(PSul, "South"); btnSair.addActionListener(this); } public void actionPerformed(ActionEvent evt) { Object origem = evt.getSource(); if (origem == btnPesqNome) { Selecao("SELECT * FROM Clientes WHERE NOME LIKE '%" + nome.getText() + "%' ORDER BY NOME"); } if (origem == btnPesqCod) { Selecao("SELECT * FROM Clientes WHERE CODIGO = " + codigo.getText() + " ORDER BY CODIGO"); } if (origem == btnSair) { try { con.close(); System.exit(0); }catch (SQLException eSQL) { // exceções de SQL eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Não foi possível desconectar o banco!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } } } public void Selecao(String sentencaSQL) { // apaga todas as linhas da tabela for (int i= modelo.getRowCount()-1; i >= 0; i--) modelo.removeRow(i); try { sentenca = con.createStatement(); registros = sentenca.executeQuery(sentencaSQL); boolean proximoRegistro = registros.next(); if (!proximoRegistro)
103
{ JOptionPane.showMessageDialog(this, "Nenhum registro foi encontrado!", "Mensagem", JOptionPane.WARNING_MESSAGE); } else do { modelo.addRow(new Object[]{ new Integer(Integer.parseInt(registros.getString("Codigo"))), registros.getString("Nome"), registros.getString("Endereco") }); } while (registros.next()); sentenca.close(); }catch (SQLException eSQL) { eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Não foi possível carregar os dados!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } } public Connection conectaBanco(String sFonte,String sUsuario,String sSenha) { Connection conexao = null; try { System.setProperty("jdbc.drivers","sun.jdbc.odbc.JdbcOdbcDriver"); conexao = DriverManager.getConnection(sFonte, sUsuario, sSenha); }catch (SQLException eSQL) { // exceções de SQL eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Falha na conexão com o banco!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); }catch (Exception e) { // demais exceções e.printStackTrace(); JOptionPane.showMessageDialog(this, "Falha na conexão com o banco!\n" + "Mensagem: " + e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } return conexao; } public static void main(String args[]) { Consulta fr = new Consulta(); fr.setVisible(true); } } class ModeloTabelaBD extends AbstractTableModel { private ArrayList linhas = null;
104
private String[] colunas = null; private boolean[] colEditavel; public ModeloTabelaBD(ArrayList lin, String[] col, boolean[] editavel) { setLinhas(lin); setColunas(col); colEditavel = editavel; } public ArrayList getLinhas() { return linhas; } public void setLinhas(ArrayList dados) { linhas = dados; } public String[] getColunas() { return colunas; } public void setColunas(String[] nomes) { colunas = nomes; } public int getColumnCount() { return colunas.length; } public int getRowCount() { return linhas.size(); } public String getColumnName(int numCol) { return colunas[numCol]; } public boolean isCellEditable(int numCol) { return colEditavel[numCol]; } public Object getValueAt(int numLin, int numCol) { Object[] linha = (Object[])getLinhas().get(numLin); return linha[numCol]; } public void setValueAt(Object dado, int numLin, int numCol)
105
{ if (isCellEditable(numCol)) { Object[] linha = (Object[])getLinhas().get(numLin); linha[numCol] = dado; fireTableDataChanged(); } } public void addRow(Object[] dados) { getLinhas().add(dados); fireTableDataChanged(); } public void removeRow(int numLin) { getLinhas().remove(numLin); fireTableDataChanged(); } public Class getColumnClass(int numCol) { Object[] linha = (Object[])getLinhas().get(0); return linha[numCol].getClass(); } }
D
D import javax.swing.*; import java.awt.*;
106
import import import import
java.awt.event.*; java.sql.*; java.util.*; javax.swing.table.*;
public class Cadastro extends JFrame implements ActionListener { private JButton btnSair; private JButton btnIncluir; private JButton btnAlterar; private JButton btnExcluir; private JButton btnPesqNome; private JTextField nome; private Connection con; private ModeloTabelaBD modelo; private JTable tabela; private Statement sentenca; private ResultSet registros; public Cadastro() { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setTitle("Consulta a Banco de Dados"); setSize(500,320); setLocation(100,100); Container P = getContentPane(); P.setLayout(new BorderLayout()); // conecta o banco con = conectaBanco("jdbc:odbc:ODBCBancoExemplo", null, null); // criação do primeiro painel JPanel PNorte = new JPanel(); PNorte.setLayout(new FlowLayout()); PNorte.add(new JLabel("Digite nome")); nome = new JTextField(13); PNorte.add(nome); btnPesqNome = new JButton("Pesquisar"); PNorte.add(btnPesqNome); btnPesqNome.addActionListener(this); P.add(PNorte, "North"); // criação da tabela // criação de um array para inserção dinâmica de objetos ArrayList dados = new ArrayList(); // criação de um array para os títulos no cabeçalho String[] colunas = new String[] { "Código", "Nome", "Endereço"}; // criação de um array para identificar se a célula é editável ou não boolean[] edicao = {false, false, false}; // criação da tabela baseada no modelo ModeloTabelaBD modelo = new ModeloTabelaBD(dados, colunas, edicao); tabela = new JTable(modelo); tabela.getColumnModel().getColumn(0).setPreferredWidth(50); tabela.getColumnModel().getColumn(0).setResizable(false); tabela.getColumnModel().getColumn(1).setPreferredWidth(200); tabela.getColumnModel().getColumn(1).setResizable(true); tabela.getColumnModel().getColumn(2).setPreferredWidth(240); tabela.getColumnModel().getColumn(2).setResizable(true); tabela.getTableHeader().setReorderingAllowed(false);
107
tabela.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tabela.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane rolagemTabela = new JScrollPane(tabela); P.add(rolagemTabela, "Center"); // criação do terceiro painel JPanel PSul = new JPanel(); btnIncluir = new JButton("Incluir"); btnAlterar = new JButton("Alterar"); btnExcluir = new JButton("Excluir"); btnSair = new JButton("Sair"); PSul.add(btnIncluir); PSul.add(btnAlterar); PSul.add(btnExcluir); PSul.add(btnSair); P.add(PSul, "South"); btnIncluir.addActionListener(this); btnAlterar.addActionListener(this); btnExcluir.addActionListener(this); btnSair.addActionListener(this); } public void actionPerformed(ActionEvent evt) { Object origem = evt.getSource(); if (origem == btnPesqNome) { Selecao("SELECT * FROM Clientes WHERE NOME LIKE '%" + nome.getText() + "%' ORDER BY NOME"); } if (origem == btnIncluir) { FrameCadastro frame = new FrameCadastro(con, null, null, null, 'I'); frame.show(); } if (origem == btnAlterar) { if (tabela.getSelectedRow()>=0) { FrameCadastro frame = new FrameCadastro(con, modelo.getValueAt(tabela.getSelectedRow(),0).toString(), modelo.getValueAt(tabela.getSelectedRow(),1).toString(), modelo.getValueAt(tabela.getSelectedRow(),2).toString(), 'A'); frame.show(); } else JOptionPane.showMessageDialog(this, "Não existe registro selecionado!\n", "Mensagem", JOptionPane.WARNING_MESSAGE); } if (origem == btnExcluir) { try { if (JOptionPane.showConfirmDialog(null,"Confirma Exclusão?", "Confirmação", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == 0) { sentenca = con.createStatement();
108
String sentencaSQL ="DELETE FROM Clientes WHERE Codigo= " + modelo.getValueAt(tabela.getSelectedRow(),0).toString(); sentenca.executeUpdate(sentencaSQL); sentenca.close(); Selecao("SELECT * FROM Clientes WHERE NOME LIKE '%" + nome.getText() + "%' ORDER BY NOME"); } }catch (SQLException eSQL) { eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Não foi possível realizar a operação!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } } if (origem == btnSair) { try { con.close(); System.exit(0); }catch (SQLException eSQL) { // exceções de SQL eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Não foi possível desconectar o banco!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } } } public void Selecao(String sentencaSQL) { // apaga todas as linhas da tabela for (int i= modelo.getRowCount()-1; i >= 0; i--) modelo.removeRow(i); try { sentenca = con.createStatement(); registros = sentenca.executeQuery(sentencaSQL); boolean proximoRegistro = registros.next(); if (!proximoRegistro) { JOptionPane.showMessageDialog(this, "Nenhum registro foi encontrado!", "Mensagem", JOptionPane.WARNING_MESSAGE); } else do { modelo.addRow(new Object[]{ new Integer(Integer.parseInt(registros.getString("Codigo"))), registros.getString("Nome"), registros.getString("Endereco") }); } while (registros.next()); sentenca.close(); }catch (SQLException eSQL) { eSQL.printStackTrace();
109
JOptionPane.showMessageDialog(this, "Não foi possível carregar os dados!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } } public Connection conectaBanco(String sFonte,String sUsuario,String sSenha) { Connection conexao = null; try { System.setProperty("jdbc.drivers","sun.jdbc.odbc.JdbcOdbcDriver"); conexao = DriverManager.getConnection(sFonte, sUsuario, sSenha); }catch (SQLException eSQL) { // exceções de SQL eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Falha na conexão com o banco!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); }catch (Exception e) { // demais exceções e.printStackTrace(); JOptionPane.showMessageDialog(this, "Falha na conexão com o banco!\n" + "Mensagem: " + e.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } return conexao; } public static void main(String args[]) { Cadastro fr = new Cadastro(); fr.setVisible(true); } } class FrameCadastro extends JFrame implements ActionListener { private JButton OK; private JButton Cancelar; private JTextField txtCodigo; private JTextField txtNome; private JTextField txtEndereco; private Connection conexao; private char TipoOperacao; public FrameCadastro(Connection con, String Cod, String Nome, String Endereco, char Tipo) { conexao = con; TipoOperacao = Tipo; setSize(250,140); setLocation(220,190); Container P = getContentPane(); JPanel painelFC = new JPanel();
110
painelFC.setLayout(new FlowLayout()); painelFC.add(new JLabel("Código")); txtCodigo = new JTextField(15); txtCodigo.setText(Cod); if (Tipo == 'A') { txtCodigo.setEditable(false); setTitle("Alteração"); } else setTitle("Inclusão"); painelFC.add(txtCodigo); painelFC.add(new JLabel("Nome")); txtNome = new JTextField(15); txtNome.setText(Nome); painelFC.add(txtNome); painelFC.add(new JLabel("Endereço")); txtEndereco = new JTextField(15); txtEndereco.setText(Endereco); painelFC.add(txtEndereco); OK = new JButton("OK"); Cancelar = new JButton("Cancelar"); painelFC.add(OK); painelFC.add(Cancelar); OK.addActionListener(this); Cancelar.addActionListener(this); P.add(painelFC,"Center"); } public void actionPerformed(ActionEvent evt) { if (evt.getSource() == OK) { if (txtCodigo.getText().trim().equals("") || txtNome.getText().trim().equals("")) { JOptionPane.showMessageDialog(this, "Campos Código e Nome devem ser preenchidos!\n", "Erro", JOptionPane.ERROR_MESSAGE); } else { try { Statement sentenca = conexao.createStatement(); String sentencaSQL = null; if (TipoOperacao == 'I') sentencaSQL = "INSERT INTO Clientes (" + "Codigo, Nome, Endereco) "+ "VALUES ("+ Integer.parseInt(txtCodigo.getText())+", '"+ txtNome.getText() + "', '" + txtEndereco.getText()+"')"; else sentencaSQL = "UPDATE Clientes SET Nome = '" + txtNome.getText() + "', Endereco = '" + txtEndereco.getText()+"' WHERE Codigo = " + Integer.parseInt(txtCodigo.getText());
111
sentenca.executeUpdate(sentencaSQL); sentenca.close(); dispose(); }catch (SQLException eSQL) { eSQL.printStackTrace(); JOptionPane.showMessageDialog(this, "Não foi possível realizar a operação!\n" + "Mensagem: " + eSQL.getMessage(), "Erro", JOptionPane.ERROR_MESSAGE); } } } if (evt.getSource() == Cancelar) { dispose(); } } }
D
D D d
3. AWT Avançado Imagens e desenhos mais complexos não podem ser feitos a partir da classe Graphics. É necessário utilizar pacotes existentes na API Java 2D, que permite produzir desenhos de mais alta qualidade.
112
3.14 Java 2D O Java 2D apresenta pacotes de classes com métodos para desenhos gráficos com um nível maior de complexidade. Alguns desses pacotes: java.awt.image, java.awt.geom, java.awt.print, java.awt.Graphics2D. Com o Java 2D é possível produzir uma variedade maior de figuras geométricas, com padrões diferentes de preenchimento, além de ter controle sobre os desenhos criados, podendo move-los, gira-los ou alonga-los.
3.15 Imagens A classe Image é a responsável pelo carregamento de imagens armazenadas em disco. Novam d
113
View more...
Comments