|
|
Marcus Becker
Exemplo de Agenda simples usando JTable e arquivos texto.
Agenda simples em Java
Bom pessoal, venho aqui postar meu primeiro artigo. É mais pra quem ta iniciando em Java, é uma agenda simples usando o JTable e um arquivo txt, venho mais para explicar a lógica que usei nos métodos de carregar e salvar os dados, para saber mais sobre o JTable leia este outro artigo( http://www.guj.com.br/java.tutorial.artigo.140.1.guj ). Dentro do JAR está todos os códigos, criei o AgendaSimples.java e o NovoMetodos.java somente para explicar melhor este artigo.
Vamos iniciar com o NovoMetodos.java.
Começo definindo o nome do arquivo de texto onde ficarão guardado os dados, para ajudar em modificações futuras uso uma variável e a defino como final, seguindo as regras o nome da variável em maiúsculas.
1 private final static String DADOS = "agenda.txt";
|
O método carregaDados() retira os dados do arquivo ?agenda.txt?.
01 protected static String carregaDados() {
02 String texto = "";
03 StringBuffer temp = new StringBuffer();
04 File arq = new File(DADOS);
05
06 try {
07 if (arq.exists()) {//Verifico se o arquivo existe.
08 // lendo arquivo
09 FileReader arquivo = new FileReader(arq);
10 BufferedReader ler = new BufferedReader(arquivo);
11 // Colocando num StringBuffer que é muito mais rápido e ocupa
12 // menos memória que +=
13 boolean fim = false;
14 //Lembrando que o método readLine() retorna null quando chega ao fim do arquivo...
15 while (!fim) {
16 String linha = ler.readLine();
17 if (linha == null)
18 fim = true;
19 else
20 temp.append(linha);
21 System.out.println("Leu:");
22
23 }
24
25 texto = temp.toString(); //convertendo o StringBuffer para String
26 // Fechando
27 ler.close();
28 arquivo.close();
29 } else
30 arq.createNewFile();// Criando Arquivo
31 } catch (IOException erro) {
32 System.out.print("Erro 01 :" + erro.toString());
33 } catch (SecurityException erro2) {
34 System.out.print("Erro 02 :" + erro2.toString());
35 }
36 return texto;
37 }
|
Espero que até aqui esteja tudo bem. Mais a frente entenderão porque este método retorna um String.
No próximo meto de nome parecido com o método anterior, eu trato dos dados vindos do arquivo de ?agenda.txt?.
Este método retorna um Array Bidimensional porque na minha tabela tenho duas colunas, cada dimensão do array é de uma coluna diferente.
01 protected static String[][] pegaDados() {
02 // Carregando Dados
03 String nome = carregaDados();// Pegando retorno de carregaDados();
04 if (nome.equals("")) {//Se não encontrou nada...
05 nome = "Agenda Simples;Marcus Becker";
06 }//Se encontrou algo...
07 // Formatando os Dados
08
09 //Lembrando que o nome e o telefone são separados pelo
10 //caractere ?;? (ponto-e-vírgula)
11 String[] arrNome = nome.split(";");
12
13 //Como para o arrNome eu coloquei o nome e o telefone, o array de
14 //dados vai ter apenas metade (só o nome) contendo 2
15 //dimensões (nome e telefone)m então divido o tamanho dele por 2.
16 String[][] dados = new String[(arrNome.length / 2)][2];
17 for (int i = 0, j = 0; i < (arrNome.length - 1); i += 2, j++) {
18 dados[j][0] = arrNome[i];
19 dados[j][1] = arrNome[i + 1];
20 }
21 //Aqui eu adiciono ao array dados os nomes e telefones, como sei que
22 //sempre vem primeiro o nome e depois o telefone
23 //referente a esse nome, adiciono os elementos 0 e 1 do arrNome, depois
24 //2 e 3, depois 4 e 5, assim por diante sempre
25 //incrementando o i em 2 (por que se não seria 0 e 1, 1 e 2 ...), já o j
26 //serve para indicar o locar no array dados onde
27 //ficarão os dados... Nem eu mesmo entendi de primeira essa parte do código.
28
29 return dados; //Retorno os dados para a tabela (veja mais a frente).
30 }
|
O método que transfere para o arquivo ?agenda.txt? os dados...
01 //Recebe os dados já formatados, separado pelo ?;?... nome;telefone;nome;telefone...
02 protected static void salvarDados(String texto) {
03 File arq = new File(DADOS);
04 try {
05 if (arq.exists()) {//Se o arquivo existir ele salva, se não, eu não sei....
06 FileWriter arquivo = new FileWriter(arq);
07 BufferedWriter grava = new BufferedWriter(arquivo);
08 grava.write(texto);
09 grava.close();
10 arquivo.close();
11 }
12 } catch (IOException e) {
13 System.out.print("Erro 01 :" + e.toString());
14 } catch (SecurityException erro2) {
15 System.out.print("Erro 02 :" + erro2.toString());
16 }
17 }
|
Sempre usem Buffer, torna tudo mais rápido. Sempre fechem o que abrirem, algum dia podem querer programar no C++ e ele não tem coletor de lixo automático. (me corrijam se eu estiver errado).
Esse método pega os dados da tabela e manda para o salvarDados(), os métodos tem nomes parecidos, mas funcionalidades diferentes. Gosto de separar bem os métodos, embora não tenha muita criatividade pra nomes, fica mais fácil na hora da manutenção ou coisa do tipo.
01 protected static void salvaTabela(DefaultTableModel modelo) { //Recebendo o objeto
02 String dados = "";
03 StringBuffer temp = new StringBuffer(); //Buffer é mais rápido...
04 for (int i = 0; i < modelo.getRowCount(); i++) {
05 String nome = (String) modelo.getValueAt(i, 0);
06 String tel = (String) modelo.getValueAt(i, 1);
07 if (!nome.equals("")) {//Se o campo nome não estiver vazio...
08 //Se o campo telefone for menor que 7 ele não contem um
09 //numero telefônico válido...
10 //então substituo ele pelo hífen.
11 if (tel.trim().length() < 7)
12 tel = "-";
13 else {
14 tel = tel.trim();//tirando espaços em branco...
15
16 //o ; é usado para separar os dado, para evitar erros
17 //inesperados eu substitui sem dó, ele por nada.
18 tel = tel.replaceAll(";", "");
19 }
20 nome = nome.trim();
21 nome = nome.replaceAll(";", "");
22 //Aqui um exemplo de um método lento, nunca usem.
23 // dados += nome + " ; " + tel + " ; ";
24 temp.append(nome + ";" + tel + ";"); // forma correta!
25 System.out.println("Nome: " + nome + "\t Tel: " + tel);
26 }
27 }
28 dados = temp.toString();
29 salvarDados(dados); //Chamando o método salva dados.
30 }
|
Aqui um método bônus, quebrei a cabeça para ordenar a minha lista telefônica.
01 protected static void ordenaTabela(DefaultTableModel modelo) {
02 StringBuffer temp = new StringBuffer();
03 String dados[] = new String[modelo.getRowCount()];
04 for (int i = 0; i < modelo.getRowCount(); i++) {
05 String valorNome = (String) modelo.getValueAt(i, 0);
06 String valorTel = (String) modelo.getValueAt(i, 1);
07 // Tirando Valores em Branco...
08 if (valorNome.trim().length() <= 0)
09 valorNome = "";
10 if (valorTel.trim().length() <= 0)
11 valorTel = "";
12
13 dados[i] = valorNome + " ;" + valorTel + ";";
14
15 }
16 Arrays.sort(dados);
17 // redefineTabela(modelo,dados);
18 for (int i = 0; i < dados.length; i++) {
19 temp.append(dados[i]);
20 System.out.println("Temp: " + dados[i]);
21 }
22 String nome = temp.toString();
23 salvarDados(nome);
24 }
|
O método Arrays.sort() ordena o array, mas só funcionou num array simples, então eu tive que fazer do meu array bidimensional um array unidimensional e ordena-lo e depois voltar tudo ao normal. Deve haver um método mais prático.
Bom, depois disso eu apenas crio o meu JTable:
1 final String[] COLUNAS = new String[]{"Nome","Telefone"};
2 DefaultTableModel modelo = new DefaultTableModel(NovoMetodos.pegaDados(),COLUNAS);
|
Explicando, criei uma classe NovosMétodos para separar a parte gráfica da parte funcional, ou quase isso. Nessa nova classe eu tenho um método que lê um arquivo e me traz tudo numa String. Escolhi o caractere ponto-e-vírgula para separar os dados, outra maneira seria separar eles por linha. O outro método separa os dados e depois joga cada um em sua dimensão para que o JTable consiga entender os dados que estou passando pra ele. Depois, quando quero salvar os dados eu faço o processo inverso. Bom... Tem mais coisa nos arquivos e qualquer dúvida estamos ai... Eu espero...
Marcus Becker
|
|
|