BlogBlogs.Com.Br

quarta-feira, 29 de abril de 2009

Java e JSON

O título apesar de estranho, é justamente disso que vou falar JSON com Java (café), andei pesquisando diversos formatos de arquivos para usar no meu TCC, dentre eles o XML, que para quem não sabe é muito custoso para um celular processar esse tipo de arquivo, o YAML (o qual não possui nenhum biblioteca para ser tratado com JME), e o ultimo é o que eu mais me encantei o JSON.

JSON foi criado baseado em JavaScript. Porém ganhou notaridade, e foi implementada por diversas linguagens, no site oficial se encontra uma biblioteca para ser usado em Java, com o codigo fonte la. Foi esse que usei nesse exemplo, podem baixar nesse link http://www.json.org/java/index.html

Muito simples trabalhar com JSON e Java. O JSON funciona como um Map, utilizando a combinação chave => valor, uma chave sempre é uma String, e o valor pode varias, os valores disponiveis para o JSON podem ser vistos no site json.org.

Após adicionar as classes ao seu projeto vamos a utilização da biblioteca.
Basicamente a biblioteca consiste nos objetos JSONObject, JSONArray e JSONException
Onde JSONObject representa um único objeto no formato JSON e JSONArray representa uma coleção de objetos.

Usando JSONObject

JSONObject obj = new JSONObject();
obj.put("nome", "Rafael");
obj.put("idade", 21);
System.out.println(obj);


a saída sera algo como:

{ "nome":"Rafael", "idade":21 }


Perfeito não? muito simples. Calma que tem mais

public class Pessoa{
private String nome;
private int idade;

//Gets e Sets
}


Criamos um objeto para comportar as alterações. e para converte-lo em JSON?

Pessoa p = new Pessoa();
p.setNome("Rafael");
p.setIdade(21);
JSONObject obj = new JSONObject(p);
System.out.println(obj);

E a saída?

{ "nome":"Rafael", "idade":21 }


Um JSONArray segue a mesma linha de raciocionio, com a diferença que vc adiciona a ele diversos JSONObject ou Strings no formato JSON. excelente para quem quer trabalhar com esse arquivo em formato leve.

É isso ai.





quarta-feira, 15 de abril de 2009

Criando seus proprios eventos no Java

A maioria do pessoal que já mexeu com Swing no Java (o que acredito que sejam a maioria do pessoal que já mexeu com java), conheçe o estilo do java tratar eventos, usando classes, assim como nossa querida classe chamada ActionListener, que algumas IDEs como o Netbeans escondem a declaração dessa interface, adotando um estilo mais delphi-style.

E normalmente o pessoal que vem do Delphi, acha estranho declarar um classe e implementar um metodo nela para executar o evento de um botão (Eu também achava isso). Porém os beneficios de adotar esse abordagem, proporciona baixo acoplamento, e seu código pode se tornar mais dinamico e orientado a objetos, não aquele código macarronico que vemos por ai, que muitas pessoas fazem, e eu também faço diversas vezes.

A vantagem de se fazer isso é que o Java não vai sobrescrever o ActionListener que já foi adicionado ao seu botão, ele vai adicionar mais um, ou seja seu botão vai executar duas ações. ou seja, vc pode separar códigos com mais facilidade, e muito mais simples. Mas bah tche como isso?

Vou mostrar como criar seus proprios eventos em Java. Imagine o seguinte problema:

"Como projetar um sistema que modele um telefone e todos os objetos que poderiam estar interessados quando ele toca?"

Rá, ai poderiamos usar o Observer, que expliquei no artigo anterior correto? Sim, poderiamos, mas não é isso que eu quero mostrar :-)

Primeiramente devemos criar o Evento, esse evento será o evento disparado toda a vez que um telefone toca, e vai ficar disponivel para os listeners, é um código realmente simples:


public class TelefoneEvent extends java.util.EventObject {

public TelefoneEvent(Telefone source) {
super(source);
}
}


Simples não, deixemos a herança cuidar disso para nós e o java que cuide de seu EventObject

Agora vamos criar nossa interface Listener, utilizando listener não impedimos a herança, e deixamos a classe livre para criar quantos listeners quiser, ou implementar se for melhor para ela, a implementação do listener


public interface TelefoneListener extends java.util.EventListener {
void telefoneTocou(TelefoneEvent e);
void telefoneAtendido(TelefoneEvent e);
}


Extendendo a interface EventListener, temos um novo evento criado, nosso telefone Listener, possui dois metodos, telefoneTocou e TelefoneAtentido, que devem ser reimplementados, uma solução bacana que o java usa também são os adapters, como KeyAdapter, que possui os metodos de KeyListener implementados sem código ou funcionalidade alguma, vc so sobrescreve os que deseja, os outros são silenciosos (não fazem nada).


public class TelefoneAdapter
implements TelefoneListener {

public void telefoneTocou(TelefoneEvent e) {}
public void telefoneAtendido(TelefoneEvent e) {}
}


Simples não, mas não é só isso, ainda não serve para nada nosso listener.


//imports omitidos
public class Telefone {
private Collection telefoneListeners = new ArrayList();

// método de suporte para testar a solução
public void tocaFone() {
disparaTelefoneTocou();
}

public void atendeFone() {
disparaTelefoneAtendido();
}

public synchronized void addTelefoneListener(TelefoneListener l) {
if(!telefoneListeners.contains(l)) {
telefoneListeners.add(l);
}
}

public synchronized void
removeTelefoneListener(TelefoneListener l) {

telefoneListeners.remove(l);
}

private void disparaTelefoneTocou() {
Collection tl;
synchronized (this) {
tl = (Collection)(((ArrayList)telefoneListeners).clone());
}
TelefoneEvent evento = new TelefoneEvent(this);
for (TelefoneListener t : tl) {
t.telefoneTocou(evento);
}
}

private void disparaTelefoneAtendido() {
Collection tl;
synchronized (this) {
tl = (Collection)(((ArrayList)telefoneListeners).clone());
}
TelefoneEvent evento = new TelefoneEvent(this);
for (TelefoneListener t : tl) {
t.telefoneAtendido(evento);
}
}
}


Essa é uma simples classe como outra qualquer, podem ver que ela possui dois metodos addTelefoneListener e removeTelefoneListener, esses metodos são padrões, em listeners vc não pode utilizar getters e setters, utilizando getter e setter perde-se o encapsulamento. Ele cria antes de disparar os eventos de cada um dos seus listeners, simples e prático.



public class SecretariaEletronica
implements TelefoneListener {

public void telefoneTocou(TelefoneEvent e) {
System.out.println("Secretaria escuta o telefone tocando.");
}

public void telefoneAtendido(TelefoneEvent e) {
System.out.println("Secretaria sabe que o telefone foi atendido.");
}
}
public class Pessoa {
public void escutaTelefone(Telefone t) {
t.addTelefoneListener(
new TelefoneAdapter() {
public void telefoneTocou(TelefoneEvent e) {
System.out.println("Eu pego!");
((Telefone)(e.getSource())).atendeFone();
}
}
);
}
}

Duas classes para melhorar a brincadeira, e vc pode criar mais classes, essas somente ajudam a ilustrar o exemplo

public class ExemploFone {
public static void main(String[] args) {
Telefone fone = new Telefone();
Pessoa fulano = new Pessoa();
SecretariaEletronica se = new SecretariaEletronica();

fone.addTelefoneListener(se);
fulano.escutaTelefone(fone);

fone.tocaFone(); // começa a brincadeira
}
}


a saida é algo assim

Secretaria escuta o telefone tocando.
Eu pego!
Secretaria sabe que o telefone foi atendid


Pode parecer complexo inicialmente, mas isso melhora e agiliza o trabalho, é muito bacana se trabalhar com listeners. Esse exemplo foi encontrado aqui e vc pode utiliza-lo, possui mais detalhes.

Uma leitura bacana, veja aqui no blog do Carlos Brando.