Escolar Documentos
Profissional Documentos
Cultura Documentos
Apostilajava
Apostilajava
LOUCADEMIA
DE JAVA
J2SE
OU
Luisius
WWW.FABIOSALVADOR.COM.BR
Pgina 2
PreDifcil
Voc pode achar Java uma linguagem complicada. No . Voc pode achar que Orientao a Objetos
um bicho de sete cabeas. No . Tudo isso muito simples. Eu vou tentar fazer parecer ainda mais
simples. Trata-se de lgica natural.
Mas eu aviso: preciso abstrair algumas noes para compreender o que se vai ler aqui. No se pode
pensar em classes como salas ou como caixas. Em objetos como variveis, como valores ou sei l o
que. preciso compreender que estamos lidando com coisas abstratas, que a princpio representam
coisas reais, mas no SO reais. Portanto, comportam-se como aquilo que so: idias. Uma classe
uma idia de um tipo de coisa. Um objeto a idia de um objeto. E uma instncia de sua classe. Um
mtodo, o qu? Uma funo? Mais ou menos. Mas tambm uma o em potencial do objeto. Ou da
classe, se for esttico.
Pode parecer difcil mas no . Poderia ser pior. Os comandos, todos palavras em ingls, poderiam ser
escritos em alemo. A sim a cobra iria fumar!
Pgina 3
WWW.FABIOSALVADOR.COM.BR
Pgina 4
Dejair, Clauber,
Pozzebon e eu turma de
Java em 2007
Pgina 5
WWW.FABIOSALVADOR.COM.BR
ndice
Prefcio....................................................................................................................................................3
PreDifcil...................................................................................................................................................3
O autor quem esse cara?..................................................................................................................4
Agradecimentos......................................................................................................................................5
ndice........................................................................................................................................................6
Nomenclaturas e badulaques.................................................................................................................8
Java a JavaScript.....................................................................................................................................................8
O que uma API......................................................................................................................................................8
J2SE, J2EE e J2ME.................................................................................................................................................8
Java Virtual Machine (JVM).....................................................................................................................................9
Java Developer Kit (JDK).........................................................................................................................................9
O que uma IDE......................................................................................................................................................9
Palavras Reservadas...............................................................................................................................................9
Coleta automtica de lixo.......................................................................................................................................10
Classes e objetos..................................................................................................................................11
Explicao Wikipdica............................................................................................................................................11
Explicao no popular..........................................................................................................................................12
Modificadores .......................................................................................................................................26
Static.......................................................................................................................................................................26
Public......................................................................................................................................................................26
Private.....................................................................................................................................................................26
Final........................................................................................................................................................................26
Protected................................................................................................................................................................27
Pacotes...................................................................................................................................................28
Tratamento de erros e excees..........................................................................................................29
Throw informado os erros classe que instanciou o objeto...............................................................................30
Tipos de Excesso.................................................................................................................................................31
Pgina 6
Eventos (Listeners)...............................................................................................................................70
ActionListener.........................................................................................................................................................70
FocusListener.........................................................................................................................................................71
KeyEvent................................................................................................................................................................72
MouseListener........................................................................................................................................................73
Pgina 7
WWW.FABIOSALVADOR.COM.BR
Java a JavaScript
A primeira confuso que existe no mundo Java entre a linguagem Java e o JavaScript. Vamos ver isso
de forma bem clara e objetiva:
JAVA uma linguagem completa, enorme e complexa utilizada para montar aplicaes completas com
acesso a Bancos de Dados constante e fins mais completos. Programar Java exige alguma prtica, e
exatamente para ensinar Java que eu escrevi este livro.
O cdigo JAVA deve ser desenvolvido, testado e depois convertido em Byte-Code, em uma operao
de compilao. O cdigo torna-se ento ilegvel e o usurio no tem acesso s fontes que deram
origem s funcionalidaes.
JAVASCRIPT uma pequena linguagem de scripts usados dentro do cdigo HTML de um site e que
executam pequenas tarefas a serem executadas do lado do cliente na conexo via Internet. O cdigo
aberto e as funcionalidades raramente passam de pequenas validaes de campos em formulrios
HTML ou efeitos de animao limitados.
A nica coisa legal sobre o JavaScript, do ponto de vista do programador Java, que as sintaxes dos
comandos so iguais. Laos de repetio, funes e outros badulaques tm a mesma forma de
escrever que os da linguagem Java.
Pgina 8
Palavras Reservadas
Existem algumas palavras em Java que no poderemos usar para designar classes, variveis ou
qualquer outro tipo de coisa. Essas palavras so comandos nativos da linguagem:
abstract continue for new assert default goto package boolean do if private break double implements
protected byte else import public case enum instanceof return catch extends int short char final
interface static class finally long strictfp const float native super true false null
Pgina 9
WWW.FABIOSALVADOR.COM.BR
No precisa se preocupar
com suas variveis
fantasmas. Eu guardo elas
para voc!
WWW.FABIOSALVADOR.COM.BR
Pgina 10
Explicao Wikipdica
Em orientao a objeto, uma classe abstrai um conjunto de objetos com caractersticas similares. Uma
classe define o comportamento de seus objetos atravs de mtodos e os estados possveis destes
objetos atravs de atributos. Em outros termos, uma classe descreve os servios providos por seus
objetos e quais informaes eles podem armazenar.
Classes no so diretamente suportadas em todas as linguagens, e so necessrias para que uma
linguagem seja orientada a objetos. Classes so os elementos primordiais de um diagrama de classes.
Estrutura da classe
Uma classe define estado e comportamento de um Objeto geralmente implementando mtodos e
atributos (nomes utilizados na maioria das linguagens modernas). Os atributos, tambm chamados de
campos (do ingls fields), indicam as possveis informaes armazenadas por um objeto de uma classe,
representando o estado de cada objeto. Os mtodos so procedimentos que formam os
comportamentos e servios oferecidos por objetos de uma classe.
Outros possveis membros de uma classe so:
* Construtores - definem o comportamento no momento da criao de um objeto de uma classe.
* Destrutor - define o comportamento no momento da destruio do objeto de uma classe.
Normalmente, como em C++, utilizado para liberar recursos do sistema (como memria).
* Propriedades - define o acesso a um estado do objeto.
* Eventos - define um ponto em que o objeto pode chamar outros procedimentos de acordo com seu
comportamento e estado interno.
Encapsulamento
Em linguagens orientadas a objetos, possvel encapsular o estado de um objeto. Em termos prticos,
isso se realiza limitando o acesso a atributos de uma classe exclusivamente atravs de seus mtodos.
Para isso, as linguagens orientadas a objeto oferecem limitadores de acesso para cada membro de uma
classe.
Tipicamente os limitadores de acesso so:
* pblico (public) - o membro pode ser acessado por qualquer classe. Os membros pblicos de uma
classe definem sua interface.
* protegido (protected) - o membro pode ser acessado apenas pela prpria classe e suas sub-classes.
* privado (private) - o membro pode ser acessado apenas pela prpria classe.
Cada linguagem de programao pode possuir limitadores de acesso prprios. Por exemplo, em Java, o
nvel de acesso padro de um membro permite que qualquer classe de seu pacote (package) possa ser
acessado. Em C#, o limitador de acesso interno (internal) permite que o membro seja acessado por
qualquer classe do Assembly (isto , da biblioteca ou executvel).
Pgina 11
WWW.FABIOSALVADOR.COM.BR
Explicao no popular
Uma classe um pedao de cdigo que vai definir um molde para a gente construir objetos.
Uma classe tem, basicamente, mtodos e atributos. Atributos so como variveis. Mtodos so como
funes. Se voc no sabe o que so Variveis e Funes, volte a ler o material sobre Lgica da
Programao.
Um exemplo prtico:
Vamos construir a classe PESSOA.
ATRIBUTOS ==> NOME (texto), IDADE (nmero inteiro) e SEXO (texto)
MTODOS ==>
Mtodo ANIVERSARIO A idade da pessoa igual idade +1 (se era 20, passa a ser 21).
Mtodo CIRGURGIA_NO_MARROCOS O sexo muda para Transexual
timo, Agora, temos, uma classe com 3 atributos e 2 mtodos. Ento, eu vou escrever o cdigo
principal do programa, aquele que ser executado linearmente (como acontecia nas linguagens Pascal,
Clipper, Cobol, Basic, e todas as antigas).
No cdigo principal, eu vou colocar uma instruo:
A Varivel P armazenar um objeto do tipo PESSOA.
P = Nova PESSOA;
P.NOME = Joozinho;
P.IDADE = 30;
P.SEXO = Homem;
WWW.FABIOSALVADOR.COM.BR
Pgina 12
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 14
Nmero inteiro.
double
boolean
char
String
Usando chaves
Segundo, preciso saber como delimitamos blocos. Blocos so coisas, como por exemplo, o conteo
de uma expresso condicional.
Linguagens como o Pascal e o Basic utilizam palavras-chave para abrir e fechar blocos. Assim, um IF
em Basic fica:
IF X = 1 THEN
// ALGUMA COISA ACONTECE
END IF
No java, porm, usamos chaves. Exatamente, chaves, aquelas que ns aprendemos a usar na quarta
srie para delimitar clculos.
If (x == 1) {
// ALGUMA COISA ACONTECE
}
Fazendo clculos
Depois, precisamos saber como fazer clculos. Os sinais matemticos so os seguintes:
+
Soma
Subtrao
Diviso
Multiplicao
S que para fazer clculos envolvendo uma certa hierarquia, no usamos parnteses, colchetes e
chaves. Usamos apenas parnteses, uns dentro dos outros.
Pgina 15
WWW.FABIOSALVADOR.COM.BR
X igual a Y
X != Y
X diferente de Y
X<Y
X menor que Y
X>Y
X maior que Y
X <= Y
X menor ou igual a Y
X >=Y
Concatenando condies
Eu posso exigir que, para alguma coisa ser executada, duas ou mais condies sejam verdadeiras.
Para isso, uso a concatenao das condies utilizando principalmente trs sinais:
&&
||
If ((Condio1) || (Condio2)) {
XOR
WWW.FABIOSALVADOR.COM.BR
Pgina 16
Agora, vamos montar um programa finalmente. Abra a sua IDE e vamos comear a escrever.
Desde os anos 80, h uma tradio que diz que o primeiro software desenvolvido por qualquer pessoa
o famoso Ol Mundo. Ns vamos fazer um pouco diferente. Nosso primeiro programa exibir na tela
uma frase que no seja essa tradicional, pois j est muito manjada.
Ento, vamos l:
public class prog {
public static void main (String[]args) {
System.out.println("Minha vingana ser maligna!");
}
}
O programa acima simplssimo. Na primeira linha, eu crio a classe PROG. Na segunda, inicio o
mtodo MAIN, que ser o principal do nosso programa. No se preocupe em entender as palavras
PUBLIC, STATIC e VOID pois h um farto material sobre isso mais adiante neste mesmo livro (ver
Modificadores). O mtodo chamado MAIN sempre rodado como principal, por um padro existente na
linguagem Java.
Depois, eu tenho uma chamada classe SYSTEM.OUT, que lida com sadas de dados para o sistema.
Eu rodo o mtodo PRINTLN, que significa mande essa frase para o prompt e quebre a linha, sendo
que eu passei uma frase para ele exibir. Pronto! Temos um programa funcional!
Pgina 17
WWW.FABIOSALVADOR.COM.BR
Pgina 18
Pgina 19
WWW.FABIOSALVADOR.COM.BR
TRUE ou
FALSE, eis a
questo!
WWW.FABIOSALVADOR.COM.BR
Pgina 20
WWW.FABIOSALVADOR.COM.BR
Este meu cdigo ficou meio longo. Eu poderia encurt-lo, fazendo o seguinte:
pessoa x;
x = new pessoa("Joo", 25);
As duas linhas acima podem ser resumidas em:
pessoa x = new pessoa (Joo, 25);
Esta frase s faz sentido se notarmos que ela resulta da justaposio de trs instrues.
PESSOA X Cria a varivel X, para guardar objeto do tipo PESSOA.
X = NEW PESSOA Cria um objeto PESSOA dentro da varivel X.
PESSOA (Joo, 25) Roda o mtodo PESSOA, de dentro da classe PESSOA, especificando dados.
H ainda outra instruo que poderia ser resumida:
String texto;
texto = x.dados();
System.out.println(texto);
Eu poderia nem usar a String TEXTO, colocando diretamente o retorno do mtodo DADOS para ser
exibido na tela.
System.out.println(x.dados());
Ao fazer redues, o cdigo da classe principal ficaria assim:
public class principal {
public static void main(String[]args) {
pessoa x = new pessoa("Joo", 25);
System.out.println(x.dados());
x.aniversario();
System.out.println(x.dados());
}
}
WWW.FABIOSALVADOR.COM.BR
Pgina 22
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 24
Pgina 25
WWW.FABIOSALVADOR.COM.BR
Static
Quando criamos uma classe, e queremos ativar seus mtodos ou pegar o valor de um atributo a partir
de outra classe, precisamos instanciar a primeira classe. Porque a classe em si no tem mtodos
funcionais e nem valor nos atributos. O objeto criado a partir desta classe que os tem.
Mas se o atributo ou o mtodo recebe o modificador static, ento este atributo ou mtodo passa a ser
ligado diretamente classe, no aos seus objetos.
Com isso, eu posso muito bem executar um mtodo static sem criar objeto algum da classe onde ele foi
escrito, bastando para isso colocar a forma nomedaclasse.nomedometodo().
Uma outra coisa que ocorre que, se eu crio a classe carro, com o atributo static cor, e eu mudo a
cor de um carro, o mesmo valor no mesmo atributo ocorre em todos os outros carros. Assim, se eu
deixar o carro que est na varivel X com a cor azul, todos os outros carros, Y, Z, ou qualquer outro,
ficaro azuis.
Public
Um atributo ou mtodo PUBLIC pode ser acessado e visto a partir de qualquer classe, de qualquer
ponto do programa, abertamente, atravs da frmula NomeDoObjeto.NomeDoAtributo ou ento
NomeDoObjeto.NomeDoMtodo(argumentos).
Private
Um mtodo que PRIVATE no poder ser acessado atravs de nenhuma outra classe a no ser os
objetos daquela classe na qual foi criado. Assim, se eu crio o mtodo PRIVATE ACELERAR, dentro da
classe Carro, eu no posso simplesmente criar o objeto Carro X e querer usar X.ACELERAR(). Eu
precisarei de outro mtodo, dentro de Carro, que ative ACELERAR por dentro.
Existem tambm atributos PRIVATE, e variveis tambm. Estes, s podem ser acessados por dentro da
classe ou mtodo onde foram criados, e servem para guardar valores de uso exclusivo naquele escopo.
Os mtodos ou atributos PRIVATE no so vistos por ningum de fora da classe de origem, nem
mesmo pelas sub-classes.
Final
O modificador Final, utilizado em alguns objetos, mtodos e variveis, faz com que estes no possam
ser reutilizados ou sobrescritos por subclasses no futuro (ou seja, mais adiante no cdigo). Algumas
funcionalidades, como as do ActionListener, s podem ser associadas a um componente qualquer (no
caso do ActionListener, botes e menus), quando existe a certeza absoluta de que estes componentes
no iro mudar ou evaporar-se por ao do programador em algum momento do cdigo. Por isso,
exige-se o uso do modificador final nestes componentes.
WWW.FABIOSALVADOR.COM.BR
Pgina 26
package filho;
public class classefilho extends classepai{
public static void main() {
classepai p = new classepai();
System.out.println(p.variavel); // ERRO: teste has protected access in pai.Pai
}
}
Pgina 27
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 28
Pgina 29
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 30
Pgina 31
WWW.FABIOSALVADOR.COM.BR
Pgina 32
Pgina 33
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 34
Pgina 35
WWW.FABIOSALVADOR.COM.BR
import sun.audio.*;
import java.io.*;
public class Tocador{
try {
InputStream arq = new FileInputStream("aha.wav");
AudioStream som = new AudioStream(arq);
AudioPlayer.player.start(som);
}
catch(Exception e) {
System.out.println(Deu pau);
}
}
}
Podemos, depois, usar um comando para fazer o som parar de tocar:
AudioPlayer.player.stop(som);
Uma outra grande jogada deste sistema que possvel tocar dois sons ao mesmo tempo. Basta criar
dois objetos do tipo InputStream e dois AudioStream. Com isso, podemos colocar uma msica e uma
batida de fundo para tocarem juntas.
Ou ainda, criar:
WWW.FABIOSALVADOR.COM.BR
Pgina 36
Pronto!
ainda no concluso, conduzido nas aulas de Java pelo lendrio Bruno, no Senac!
Ou ainda...
Pode animar o trabalho da Contabilidade, que muito montono, fazendo o primeiro sistema contbil
com trilha sonora tocada pelo
Sha Na Na!
Ou melhor ainda...
Faa uma juno de msicas e coloque uma banda impensvel para tocar: por qu escolher? Bote
Pgina 37
COM
os caras do
WWW.FABIOSALVADOR.COM.BR
Sha Na Na!
WWW.FABIOSALVADOR.COM.BR
Pgina 38
Pgina 39
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 40
SEUS PROBLEMAS
ACABARAM!
Vamos trabalhar agora a interface grfica do
seu programa em Java! Leia as prximas
pginas e sua vida ser iluminada!
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 42
Pgina 43
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 44
Pgina 45
WWW.FABIOSALVADOR.COM.BR
Este programa comea normalmente com a criao da JFrame e tudo mais. E ele termina normalmente.
Na verdade, seria mais um programa banal, desses que desenvolvemos todos os dias, no fosse pelo
fato de eu ter adicionado uns objeto novos tela. Esses objetos novos so como JTextFields. S que
com uma mscara.
A mscara, no caso um MakFormatter, um objeto de uma classe criada apenas com o fim de
associar-se a JFormattedTextFields e formar um campo com parmetros para digitao.
No caso, o formato da Dat, por exemplo, j mostrar a TextField com as barras. J os sinais de
sustenido ficaro em branco, aguardando que o usurio digite nmeros - EU DISSE NMEROS! NO
LETRAS!
Se voc quiser que o usurio possa digitar o que quiser em uma determinada posio, basta colocar um
asterisco ao invs do sustenido.
Assim como a JTextField, sua variante Formatted precis ser adicionada tela. Ento, vamos acabar
logo esse programa.
tela.add(txtCPF);
tela.add(txtData);
tela.add(txtCNPJ);
tela.setLayout(null);
tela.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE);
tela.setVisible(true);
}
}
WWW.FABIOSALVADOR.COM.BR
Pgina 46
Pgina 47
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 48
Pgina 49
WWW.FABIOSALVADOR.COM.BR
JOptionPane.INFORMATION_MESSAGE
JOptionPane.WARNING_MESSAGE
JOptionPane.QUESTION_MESSAGE
JOptionPane.PLAIN_MESSAGE
WWW.FABIOSALVADOR.COM.BR
Pgina 50
YES_NO_OPTION
Botes Yes e No
OK_CANCEL_OPTION
Botes OK e Cancel
PLAN_MESSAGE
Pgina 51
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 52
Pgina 53
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 54
Uma JCheckBox um daqueles componentes em que vemos uma caixinha quadrada com uma frase ao
lado, e podemos marcar ou desmarcar a caixinha quadrada. As CheckBoxes no so usadas para fazer
escolhas com apenas uma opo vlida, podendo ser todas marcadas ou todas desmarcadas
livremente, desde que o programador no coloque restries no prprio cdigo.
import java.awt.event.*;
import javax.swing.*;
public class checa {
public static void main(String[]args) {
JFrame tela = new JFrame("Checks!");
tela.setBounds(10,10,800,600);
tela.setLayout(null);
}
}
Depois, para termos um retorno do valor de cada JCheckBox, utilizamos o mtodo isSelected(), que
retorna um valor boolean. Assim:
boolean x = pizza.isSelected();
Ou ainda:
If (pizza.isSelected()) {
- Funes a serem executadas.
}
Na pgina seguinte, temos um cdigo de exemplo sobre como utilizar a CheckBox e ter seu retorno
atravs de um boto ao qual foi adicionado um ActionListener.
Voc vai ver ActionListeners ao longo dos nossos exemplos, ento, para no ficar confuso demais, por
favor d uma lida no captulo que se chama Eventos (Listeners).
Pgina 55
WWW.FABIOSALVADOR.COM.BR
tela.setBounds(10,10,800,600);
tela.setLayout(null);p
final JCheckBox pizza = new JCheckBox("Quero uma Pizza.");
refri.setBounds(100,80,200,35);
pizza.setSelected(true);
JButton botao = new JButton("Fazer pedido");
botao.setBounds(100,150,200,35);
botao.addActionListener(new ActionListener() {
tela.add(pizza);
tela.add(refri);
tela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tela.setVisible(true);
}
}
WWW.FABIOSALVADOR.COM.BR
Pgina 56
Pgina 57
WWW.FABIOSALVADOR.COM.BR
programador.setBounds(20,60,250,35);
ButtonGroup grupo = new ButtonGroup();
grupo.add(designer);
grupo.add(programador);
programador.setSelected(true);
}
});
tela.add(botao);
tela.add(designer);
tela.add(programador);
tela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tela.setVisible(true);
}
}
WWW.FABIOSALVADOR.COM.BR
Pgina 58
A JComboBox desenha uma caixinha parecida com a JTextField, s que ao invs de termos um texto a
escrever, temos uma seta com a qual abrimos uma fileira de possibilidades de preenchimento para a
caixa.
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
public class combo {
public static void main(String[]args){
JFrame tela = new JFrame("Combo");
tela.setBounds(10,10,800,600);
JComboBox comb = new JComboBox();
comb.setBounds(100,100,150,35);
comb.addItem("Gacho");
comb.addItem("Baiano");
comb.addItem("Paulista");
comb.addItem("Carioca");
comb.setEditable(false);
comb.setSelectedIndex(0);
tela.setLayout(null);
tela.add(comb);
tela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tela.setVisible(true);
}
}
Para obter o retorno das informaes, temos uma srie de mtodos que nos dizem o que, afinal, o
usurio escolheu. Os mais usados so os seguintes:
comb.getSelectedItem()
Este retorna o texto que est na caixa do Combo. Poder ser usado especialmente para quando
colocamos o setEditable em TRUE, ou seja, quando o usurio pode escrever na caixa. O retorno deste
mtodo uma String, com o texto da caixa.
comb.getSelectedIndex();
Este mtodo retorna o ndice do item selecionado (como se as opes fossem um vetor). Caso o
usurio possa escrever algo na caixa de texto, e escreva alguma coisa que no consta das opes
fornecidas, ento o ndice que retorna o -1. Portanto, s use se o setEditable for FALSE.
Pgina 59
WWW.FABIOSALVADOR.COM.BR
Este componente utilizado para criarmos um daqueles menus separados em abas, as quais podem
ser alternadas na parte superior da tela.
Uma TabbedPane funciona de maneira bem simples: primeiro, criamos nossas JTextFields, JLabels,
Combos, Radios, Checks e o que mais quisermos. Depois, colocamos tudo isso dentro de JPanels.
Em seguida, dizemos ao Java que cada JPanel uma das abas da JTabbedPane.
import javax.swing.*;
import java.awt.*;
public class table {
WWW.FABIOSALVADOR.COM.BR
Pgina 60
Este programa em si no
tem quase nada de novo:
criamos uma JFrame, um
JTextField, e damos
setBounds em tudo.
Pgina 61
WWW.FABIOSALVADOR.COM.BR
import java.awt.*;
public class tabelas {
public static void main(String[]args) {
JFrame tela = new JFrame("Tabelas");
tela.setBounds(0,0,1024,768);
Aqui, eu crio a JTable e dou-lhe
JTable tabela = new JTable();
uma dimenso, adicionando-a
tabela.setBounds(10,10,200,400); tela logo em seguida.
tela.add(tabela);
String[] colunas = {"Nome", "Salrio"};
modelo.setColumnIdentifiers(colunas);
modelo.setRowCount(0);
Com o mtodo setRowCount, dizemos quantas linhas da tabela devero ficar (o resto
some). Eu disse que so ZERO, ou seja, zerei a tabela. Este procedimento deve ser
feito sempre no comeo do processo de carregar dados na tabela.
WWW.FABIOSALVADOR.COM.BR
Pgina 62
objetos[0] = "Lula-l";
objetos[1] = "12000";
modelo.addRow(objetos);
tabela.setModel(modelo);
tela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tela.setLayout(null);
tela.setVisible(true); O resto apenas a perfumaria de sempre: tirar o
Layout, especificar o DefaultCloreOperation, e dar um
setVisible na tela.
}
Depois, eu posso conseguir o retorno de dados da tabela, por exemplo, quando o usurio clicar duas
vezes na minha tabela. Para isso, bastaria adicionar aps o tela.setVisible(true) um MouseListener
tabela.addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 64
if (opcao==JFileChooser.APPROVE_OPTION) {
File nomearquivo = filex.getSelectedFile();
try {
InputStream arq = new FileInputStream(nomearquivo);
AudioStream som = new AudioStream(arq);
AudioPlayer.player.start(som);
O resto do cdigo no faz parte realmente
System.out.println("Tocando");
do JFileChooser trata-se do cdigo j
}
visto para tocar msica. O usurio dever
catch(Exception e) {
selecionar um arquivo WAV para tocar.
System.out.println("Deu merda");
}
O resto do cdigo so nossos conhecidos
comandos de exibir o JFrame (quando o
JFrame for fechado, o programa cair fora
do ar e a msica cessar).
}
tela.setBounds(10,10,800,600);
tela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tela.setVisible(true);
}
}
Pgina 65
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 66
telinha1.setBounds(0,0,300,400);
telinha2.setBounds(0,0,300,400);
telinha1.hide();
telinha2.hide();
telinha1.setDefaultCloseOperation(JInternalFrame.HIDE_ON_CLOSE);
telinha2.setDefaultCloseOperation(JInternalFrame.HIDE_ON_CLOSE);
Note que eu escolhi, como DefaultCloseOperation, o HIDE_ON_CLOSE. Isso quer dizer
que, quando fechadas, minhas telinhas internas no sero descarregadas da memria (o
que aconteceria se fosse DISPOSE_ON_CLOSE) e nem o programa sair do ar (o que
aconteceria com EXIT_ON_CLOSE). As telinhas vo simplesmente ser escondidas,
ficando invisveis.
Pgina 67
WWW.FABIOSALVADOR.COM.BR
barra.add(menu);
menu.add(t1);
menu.add(t2);
t1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
telinha1.show();
}
});
t2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
telinha2.show();
}
});
Agora, aqui importante notar como as coisas so
estruturadas umas dentro das outras. Eu tenho minhas
JInternalFrames (telinha e telinha2) presas dentro de um
deska.add(telinha1);
JDesktopPane (deska). E o JDesktopPane preso dentro da
deska.add(telinha2);
JFrame (tela).
tela.add(deska);
tela.setJMenuBar(barra);
tela.setBounds(10,10,800,600);
tela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tela.setVisible(true);
}
}
WWW.FABIOSALVADOR.COM.BR
Pgina 68
Object[] opcoes = {
"Opes",
"Opo 1",
"Opo 2",
Este primeiro n, eu criei importando opcoes[0], que a palavra
"Opo 3"
Opes - este n ser paii de outros que eu criarei depois.
};
DefaultMutableTreeNode nos = new DefaultMutableTreeNode(opcoes[0]);
DefaultMutableTreeNode child;
for(int cont = 1; cont < opcoes.length; cont++){
Depois de criar o n nos, eu criei o child - este guardar os
Object obj = opcoes[cont];
child = new DefaultMutableTreeNode(obj); filhotes do nos. Eu usarei um nico objeto do tipo n, o child,
que ser reutilizado vrias vezes.
nos.add(child);
}
Veja que eu fiz um FOR. Ele roda todos os elementos do Array
opcoes, menos o de ndice zero (que a palavra Opes, e
que eu j usei para fazer o n pai).
JTree tri = new JTree(nos);
tri.setBounds(0,0,200,400);
tela.add(tri);
tela.setLayout(null);
tela.setVisible(true);
tela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Depois de adicionar todos os ns filhotes, a varivel child torna-se intil. Mas a varivel nos
agora guarda o n que tem a palavra Opes e mais todos os sub-ns adicionados no processo
que rodamos no FOR. Assim, temos o menu completinho.
Pgina 69
WWW.FABIOSALVADOR.COM.BR
A declarao acima um mtodo, o mesmo que citamos antes. O argumento dele um evento ocorrido
que fica em uma lista de eventos possveis determinados pelo usurio, como veremos mais adiante.
if ("botao1".equals(e.getActionCommand())) {
JOptionPane.showMessageDialog(null, "Apertou o boto!", "Ol!",
JOptionPane.INFORMATION_MESSAGE);
}
Aqui, a coisa simples: caso o ActionCommand do evento e seja igual a botao1, uma caixa com
uma mensagem aparecer na tela.
}
};
Quando alteramos um mtodo da classe no momento de sua instanciao, terminamos com chaves e
ponto-e-vrgula; Agora, vem o final, montar a tela e colocar este ActionListener para funcionar.
botao.setActionCommand("botao1");
botao.addActionListener(ac);
Acima, eu determinei qual o ActionCommand do boto (no caso botao1), e depois adicionei o
ActionListener ao boto, fazendo com que ele passe a detectar quando o usurio clica no boto,
acionando o mtodo ActionPerformed.
tela.setLayout(null);
tela.add(botao);
tela.setVisible(true);
}
}
WWW.FABIOSALVADOR.COM.BR
Pgina 70
Pgina 71
WWW.FABIOSALVADOR.COM.BR
tex.setBackground(Color.BLACK);
tex.setForeground(Color.YELLOW);
}
Acima, defini a ao a executar para quando o usurio tira o dedo do boto que havia pressionado.
public void keyTyped(KeyEvent e) {
tex.addKeyListener(key);
tela.setLayout(null);
tela.add(tex);
tela.add(tex2);
tela.setVisible(true);
}
}
NOTA: Pode-se detectar qual o boto apertado pelo usurio explorando a varivel KeyEvent e, que
retornar o cdigo da tecla apertada.
WWW.FABIOSALVADOR.COM.BR
Pgina 72
Pgina 73
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 74
Converso de dados
Transformar Strings em int
int qualquercoisa = Integer.parseInt(stringqualquer);
Transformar int em String
stringqualquer = Integer.toString(intzinho);
Transformar String em double
double numero = Double.ValueOf(stringzinha).doubleValue();
Transformar double em String
stringzinha = Double.toString(doublequalquer);
Transformar double em int
int x = (int) numerodouble;
Pgina 75
WWW.FABIOSALVADOR.COM.BR
Ringo no minimiza!
MATA!
Ordenando a uma JFrame que abra em modo
maximizado
Existe um mtodo, o setExtendedState, no qual podemos colocar como valor MAXIMIZED_BOTH, o
que nos trar a JFrame maximizada. Se for um JInternalFrame, ele vir maximizado dentro do
JDesktopPane ao qual pertence.
Sintaxe:
tela.setExtendedState(JFrame.MAXIMIZED_BOTH);
Existe uma grande diferena entre maximizar e simplesmente descobrir o tamanho da tela,
redimensionando o JFrame para o tamanho da tela. Quando usamos redimensionamento com
setBounds ou setSize, o programa continua tendo o boto de MAXIMIZAR, o que no acontece com o
caso explicado acima.
WWW.FABIOSALVADOR.COM.BR
Pgina 76
Pgina 77
WWW.FABIOSALVADOR.COM.BR
Nestas 4 linhas, eu
descobri o tamanho da
tela e converti suas
dimenses em INT.
WWW.FABIOSALVADOR.COM.BR
Pgina 78
}
}
Pgina 79
tela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
tela.setExtendedState(JFrame.MAXIMIZED_BOTH);
tela.setVisible(true);
Os comandos finais so a adio do JDesktopPane dentro da tela,
e os tradicionais comandos que colocam a tela no ar. Ou seja,
nosso habitual final de cdigo de todos os exemplos. S que aqui a
tela abre maximizada.
WWW.FABIOSALVADOR.COM.BR
Ateno!
No passe deste ponto sem ler algum material sobre SQL!
Voc deve conhecer SQL e bem provvel que, em breve, haja
tambm uma obra do mesmo autor sobre SQL.
Se voc no manja nada de SQL e nem sabe o que um banco
de dados, ento no prossiga! Procure informar-se primeiro.
Se voc no sabe como funciona um Banco de Dados,
NO PROSSIGA!
Eu avisei! Os incrdulos iro pagar!!!! h h h ha!!
WWW.FABIOSALVADOR.COM.BR
Pgina 80
Pgina 81
WWW.FABIOSALVADOR.COM.BR
Depois, v ao boto Adicionar e escolha o tipo de base de dados. No caso, eu escolho neste exemplo
a do Access.
Da, aparecer a caixinha abaixo. Voc precisar encontrar o arquivo do banco de dados Access, que
WWW.FABIOSALVADOR.COM.BR
Pgina 82
No campo Descrio, escreva um nome (um Alias) para o seu banco de dados. Nada muito
complicado. Opte por nomes curtos. Coisas como bd_compras ou algo assim.
O uso de ODBC para conectar base de dados serve para a maior parte dos SGBD (Sistemas
Gerenciadores de Banco de Dados) existentes na face da Terra. Voc pode implementar nos seus
clientes se quiser. S que h outras maneiras de ligar um Banco de Dados a um programa.
Em seguida, voc dever criar sua aplicao Java com interao com o Banco de Dados. Vamos em
frente ento.
Pgina 83
WWW.FABIOSALVADOR.COM.BR
Pgina 84
Pgina 85
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 86
Pgina 87
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 88
botao.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JOptionPane.showMessageDialog(null, "Opa! Pidi-pra-par-parou!");
conector();
tela.dispose();
}
});
tela.add(botao);
tela.setLayout(null);
tela.setVisible(true);
tela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
A seguir, eu vou construir um mtodo que realmente abre a base de dados e faz alguma coisa com ela:
A primeira coisa carregar alguma coisa para a Connection que aqui tem o nome de
con. Eu vou passar como parmetros uma URL formada pelo IP do servidor, barra,
nome da base de dados. E vou passar o username e a senha.
try {
String url = "jdbc:mysql://192.168.86.25/fabio";
con = DriverManager.getConnection(url, "root", "churros");
Statement comandoSQL = con.createStatement();
Pgina 89
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 90
Pgina 91
WWW.FABIOSALVADOR.COM.BR
Surge ento uma caixinha com configuraes de pgina. Aqui se escolhe o tipo de papel e as margens.
Para quem conhece Word e outros derivados, esta tela no tem nenhuma novidade.
Ao iniciar o novo projeto, surge para ns uma tela com uma folha de papel em branco. Esta folha est
separada em partes. Cada parte corresponde a um pedao do documento que vai sair impresso.
TITLE o ttulo do documento, e aparece apenas na primeira pgina. Serve para fazer capas e coisas
assim.
PAGEHEADER o cabealho do documento. Aparecer no topo de todas as pginas.
COLUMSNHEADER So os cabealhos das colunas. Aparecero sempre antes dos dados, mas ns
podemos fazer o IReport repetir estes cabealhos dentro dos grupos (veremos depois o que so grupos
de dados).
DETAIL Aqui vo os dados em si, empilhados, correndo uma tabela do banco de dados qualquer.
COLUMNFOOTER o rodap do espao iniciado com ColumnHeaders.
WWW.FABIOSALVADOR.COM.BR
Pgina 92
Aqui, no temos grande coisa. Vemos as bandas em uma lista na esquerda, e ao lado o Band Width. O
Band Width representa a altura de cada banda. Se colocarmos um zero ali, a banda desaparece.
J o campo Split Alowed, quando marcado, permite que uma determinada banda, ao no caber em
uma nica pgina, seja repartida. Se estiver desmarcada, ela fica presa primeira pgina e sai cortada
e a, azar!
Pgina 93
WWW.FABIOSALVADOR.COM.BR
Dentro de Conexes, ns podemos criar conexes com o BD. Trata-se de um exerccio simples de
preencher campos. Se voc optar por escrever o endereo do servidor e o nome da base de dados nos
campos designados para tal, nunca se esquea de clicar em Wizard, para passar estes parmetros para
a string de conexo no segundo campo, de cima para baixo. ele quem vale na hora de conectar.
No confunda: Server Address um endereo IP ou domnio do servidor para encontra-lo em uma rede.
Se o prprio PC onde est sendo gerado o IReport for o portador do BD usado, ento ser preciso
escrever localhost.
No se preocupe com o fato de estarmos usando uma conexo com IP e tudo para ligar nosso IReport
a uma base de dados. Isso s vai ter validade para usarmos nos testes dos relatrios dos nossos
sistemas. Na hora de rodar o programa nos computadores de um cliente, por exemplo, ns podemos
dizer, atravs do programa em Java, qual o IP do Banco de Dados. Ento, crie seu Report com uma
base de dados que te sirva para os testes do programa, e depois quando ele for implementado nos
clientes, os Reports continuaro a funcionar numa boa.
Depois, no prprio menu Fonte de Dados, escolha a opo Consultas do Relatrio. Aqui, voc deve ir
Report SQL Query e escrever uma Query SQL que vai retornar dados, preenchendo o relatrio com
WWW.FABIOSALVADOR.COM.BR
Pgina 94
De volta tela principal do IReports, chegou a hora de dar uma olhada no menu da parte inferior
esquerda. L, vamos ativar a aba Objects Library, que contm os objetos que formam o nosso relatrio.
Os principais tipos de dados a colocar dentro do relatrio so os FIELDS, os VARIABLES e os
PARAMETERS.
FIELDS So campos tirados da base de dados. Colocar um Field faz o Report imprimir os dados que
aquele campo contm.
VARIABLES So variveis. Podemos cria-las para executar funes de soma ou outras coisas
parecidas.
PARAMETERS So utilizado para importar os valores passados pelo programa feito em Java. Estes
parmetros devem ser passados no momento de se chamar a impresso.
Eu posso criar variveis e parmetros, clicando com o boto direito sobre os menos da esquerda e
escolhendo ADD, e ento, o que eu quero adicionar.
Pgina 95
WWW.FABIOSALVADOR.COM.BR
Para fazer os campos, variveis e parmetros aparecerem no Report, eu devo arrasta-los para dentro
da folha branca, na sesso que eu quiser.
No meu exemplo, eu usei como banco de dados a base de dados do meu site, que alis, voc deveria
visitar. Mas isso outra histria. O fato que eu sei meu site, e com minha Query SQL, mandei retornar
os ttulos das colunas de opinio do site e o nome do autor de cada uma. Obviamente, aparecer uma
enorme lista de ttulos com nomes repetidos, pois eu mandei ordenar pelo cdigo do autor.
Ento, o resultado ser esse:
WWW.FABIOSALVADOR.COM.BR
Pgina 96
Aparecero os nomes dos grupos que ns temos no Report, mas como no temos nenhum ainda, no
aparecer nada disponvel a no ser o boto NEW, que ns vamos pressionar, claro.
Uma vez dentro do quadro de criao de grupos, precisamos definir duas coisas: o nome do nosso
grupo e qual ser a expresso agrupadora dele. O nome algo bem simples, basta escrever qualquer
coisa ali dentro.
Eu vou escrever Grupex.
J a expresso segue uma lgica mais complexa, mas no muito. preciso dizer que tipo de coisa se
est usando como parmetro de agrupamento se um campo do banco de dados, se um Parameter
ou se uma Variable. Para distinguir um do outro, usa-se uma letra (F para Field, campo; V para
Variable; P para Parameter).
Eu, no caso, estou agrupando as colunas dos meus articulistas de opinio dentro de grupos formados
pelas colunas de um mesmo autor. Ento, vou aproveitar o campo NOME, escrevendo a expresso
$F{nome}.
Existem umas caixinhas para eu marcar tambm. Vamos ver o que elas fazem.
Start on a New Column repete os ColumnHeaders dentro do grupo.
Start on a New Page Ele quebra a pgina a cada vez que um novo grupo vai se iniciar.
Reset Page Number A primeira pgina de cada grupo ser numerada como se fosse a primeira do
relatrio, caso usemos numerao de pginas (veremos isso adiante).
Print header on each Page Caso o grupo extenda-se por mais de uma pgina, o GroupHeader ser
repetido em cada uma delas.
Pgina 97
WWW.FABIOSALVADOR.COM.BR
No meu exemplo, veja que eu usei o GrupexHeader para colocar o NOME do colunista cujos textos
sero listados, e coloquei um retngulo meio cilndrico (ou sei l o que aquilo ali). Esse desenho se
repetir como cabealho de cada grupo formado pelos textos de um mesmo autor. O resultado fica
assim:
WWW.FABIOSALVADOR.COM.BR
Pgina 98
Testando o Report
Quando eu crio um Report, como sei que ele est ficando legal? Atravs da F? No! Eu uso botes
exatamente criados para testes.
Este comando testa seu relatrio com
os dados do Banco de Dados, dando uma viso
realista do trabalho como ficar no fim.
Este boto roda o relatrio com uma base de dados
vazia, apenas para conferirmos o visual que
ficar. Isso evita que tenhamos que rodar
consultas pesadas ao BD a cada pequeno teste.
Botes do IReport
J que viemos at aqui, vamos ver ento os botes do IReport e para que servem:
O boto com o T insere um campo
de texto esttico algo que
escrevemos aqui como se fosse
uma Label apenas para indicar
que dado vem a seguir ou para
mostrar informaes fixas.
Pgina 99
WWW.FABIOSALVADOR.COM.BR
S para fins de demonstrao, veja que eu estou criando uma varivel que vai calcular quantas colunas
de opinio cada colunista escreveu. Eu defini o tipo dela como Java.lang.Integer, ou seja, um nmero
inteiro. Coloquei o tipo de clculo dela em COUNT, ou seja, contagem (ela vai ficar somando cada
rodada de Detail que rolar, ou seja, vai contar quantos registros ocorreram no Detail).
Eu preciso dizer o que, afinal de contas, esta varivel est calculando. Ento, eu defini isso em Variable
Expression, onde botei o campo titulo tirado da minha base de dados.
Veja que em Reset Type, eu marquei Group. Ou seja, a contagem ser reiniciada a cada grupo. Eu
preciso definir qual grupo, ento marquei o Grupex na ComboBox ao lado.
Por fim, eu preciso inicializar esta varivel com algum valor. Eu coloquei um New Integer, um novo
nmero Integer, que zero.
No final, eu vou colocar minha varivel logo no final da lista de cada colunista (em GrupexFooter), e
vejamos o resultado:
WWW.FABIOSALVADOR.COM.BR
Pgina 100
Depois, veremos como usar Parameters. No vem ao caso agora. Eu vou finalizar o processo salvando
o arquivo JRXML para dentro da pasta onde o meu programa Java est sendo desenvolvido. Mais
tarde, este JRXML dever acompanhar o resto do projeto tambm.
Pgina 101
WWW.FABIOSALVADOR.COM.BR
Pgina 102
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 104
Agora, eu vou criar o JAR em si. Primeiro, eu clico com o boto direito sobre o nome do meu projeto e
escolho EXPORT.
Pgina 105
WWW.FABIOSALVADOR.COM.BR
Em seguida, eu entro em uma tela na qual devo dar um BROWSE e escolher a pasta e nome de
arquivo para o meu projeto fechado. Vemos isso na figura abaixo.
Depois de clicar NEXT, eu passo por uma tela na qual devo dizer se quero fechar no JAR at mesmo
classes com erros ou Warnings. Warnings so avisos sobre criao de variveis que no sero usadas
e coisas do tipo. Nada que trave o programa.
WWW.FABIOSALVADOR.COM.BR
Pgina 106
Para que o seu programa funcione no computador do seu cliente, voc vai ter que instalar nele a JRE,
que pode ser baixada da Internet gratuitamente sem nenhum problema.
Agora, se o computador do cliente j tinha uma JRE, ou se est se confundindo na hora de abrir seus
JARs, o procedimento para consertar isso muito simples. Isso normalmente ocorre no Windows. Basta
desassociar os JARs de qualquer programa, que o Windows mesmo achar a maneira certa de abrir o
programa.
Para fazer isso, abra Meu Computador, v ao menu Ferramentas, abra Opes da pasta, v at a aba
Tipos de Arquivo e EXCLUA o formato JAR. Pronto! Seu Windows perdeu as configuraes que o
estavam confundindo e agora obedecer JRE bem bonitinho, abrindo seu JAR e rodando o programa.
Pgina 107
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 108
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 110
Agora, eu vou criar o Report consultando nesta tabela para procurar dados. Para isso, sigo o
procedimento que j vimos criando um Report perfeitamente normal.
S que l pelas tantas, eu vou inserir um componente Cdigo de Barras ao lado do nome dos produtos
na banda Detail. E vou clicar duas vezes neste componente criado, fazendo ento uma edio de suas
Properties.
Ao atribuir dentro da Barcode Expression o valor de um campo, eu fao com que o Ireport desenhe o
cdigo de barras para aquele nmero. Assim, fica fcil criar boletos, controles de patrimnio e outras
utilidades que necessitem de cdigo de barras.
O resultado final o seguinte:
Pgina 111
WWW.FABIOSALVADOR.COM.BR
WWW.FABIOSALVADOR.COM.BR
Pgina 112
as Himself
as Himself
as Himself
as Himself
as Himself and Angry JOptionPane Face
as Himself
as Sir Not Apeearing in this Film
as Himself
as Himself
as Himself
as Himself
as Himself
as Himself
as Scrates (quote by Rene Descartes)
as Herself
as Sha-na-na's "Bowzer"
as Sha-na-na Singers
as Hamlet, prince of Denmark
as Himself
as Ringo
as London After Midnight Monster
Java By
Sun Microsystems
Soundtrack
"Blue Moon", by The Marcels
"La Vie en Rose", by Edith Piaf
Directed by
Fbio Burch Salvador
Produced by
Senac So Leopoldo
Printed by
ACCpias
Chief of Project Engeneering
Sergio Costi
Special Cleaning Specialist
Tia Rose
Chief Manager of Development Compilator Programator Memory-Gastator
Daniel Beckel
Sample Codes Inspirator
Angus McGyver
Food and Coke Supplies Manager
Saddam da Feitoria
Pgina 113
WWW.FABIOSALVADOR.COM.BR
2008 Fbio Burch Salvador All rights reserved by the Laws of Moldania
(qu? No sabe onde fica a Moldnia, imbecil? Fica entre a Eslovnia e a Sbrnia)
WWW.FABIOSALVADOR.COM.BR
Pgina 114