Como impressionar seus amigos com Java
Postado em 05. dez, 2006 por Thadeu Russo em Java
Olá, já estou a algum tempo na Caelum mas só agora estreando no blog e, para compensar a demora, resolvi fazer um pouco diferente. O título deve estar chamando a atenção e antes de colocar o assunto de verdade (está bem, sei que estou valorizando um pouco), vou apenas lembrar da pessoa que me mostrou o assunto e da que me sugeriu colocar no blog. Ricardo e Paulo. Pronto, direto ao assunto.
Certamente muitos desenvolvedores Java já passaram pelo problema de ter de mostrar alguns recursos interessantes da plataforma. Certamente o HelloWorld não é um grande atrativo. Talvez demonstrar como é fácil fazer relacionamentos com tabelas associativas e chaves compostas através do Hibernate ajude bastante, mas ainda falta certo apelo visual.
Existe uma API feita em Java de livre uso, chamada Prefuse que utiliza-se do Java 2D para tornar simples tarefas complicadas visualmente, como por exemplo, renderizar grafos de maneira visualmente agradável e ainda por cima animada, permitindo inclusive uma interação do usuário através de drag-and-drop.
Uma aplicação mais prática e um tanto quanto útil, é a representação do relacionamento de tabelas ou mesmo de objetos, quando você precisa navegar entre uma grande quantidade de informações e quer uma maneira mais rápida em vez de pular de página em página. A idéia deste post é apenas fazer a introdução ao prefuse, sem entrar em muitos detalhes da API.
Veja abaixo o código para criar uma aplicação mostrando visualmente o relacionamento das fronteiras dos estados do Brasil.
/**
* @author Thadeu Russo
*
*/
public class Visualizacao {
/** Display onde será desenhada a visualização */
private Display display;
/** Lista de actions relacionadas ao layout */
private ActionList layout;
/** Lista de actions relacionada as cores */
private ActionList color;
/** renderizador dos labels */
private LabelRenderer labelRenderer;
/**
* Carrega as informações que estao no
* arquivo sourceFile para um novo grafo
* @param sourceFile
* @return graph
* @throws DataIOException no caso de
* problemas com a leitura dos dados
* */
private Graph loadGraph(String sourceFile) throws DataIOException{
return new GraphMLReader().readGraph(sourceFile);
}
/**
* Este método retorna o display para a visualization informada
* @return display
* @throws DataIOException
* */
private Display getDisplay() throws DataIOException {
Visualization visualization = this.buildVisualization(
this.loadGraph("data/brasil.xml")
);
/** troquei a visualização? */
if (this.display == null || !this.display.getVisualization().equals(visualization)) {
this.display = new Display(visualization);
this.display.setSize(720, 500);
this.display.addControlListener(new DragControl());
this.display.addControlListener(new PanControl());
this.display.addControlListener(new ZoomControl());
this.display.addControlListener(new WheelZoomControl());
this.display.pan(200, 350);
this.display.setForeground(Color.GRAY);
this.display.setBackground(Color.WHITE);
}
return this.display;
}
/**
* Recupera as actions relacionadas ao layout
* @return ActionList relacionados ao layout
* */
private ActionList getLayout() {
if (this.layout == null) {
this.layout = new ActionList(Activity.INFINITY);
this.layout.add(new ForceDirectedLayout("graph"));
this.layout.add(new RepaintAction());
}
return this.layout;
}
/**
* Recupera a configuração de cores e actions relacionadas a esta
* @return action list
* */
private ActionList getColor(){
if (this.color == null) {
DataColorAction fill = new DataColorAction("graph.nodes", "region",
Constants.NOMINAL, VisualItem.FILLCOLOR, this
.getColorPalette());
ColorAction text = new ColorAction("graph.nodes",
VisualItem.TEXTCOLOR, ColorLib.gray(0));
ColorAction edges = new ColorAction("graph.edges",
VisualItem.STROKECOLOR, ColorLib.gray(200));
this.color = new ActionList();
color.add(fill);
color.add(text);
color.add(edges);
}
return this.color;
}
/**
* Monta a visualização a ser mostrada no display
* @param graph O grafo a ser renderizado
* @return visualization
* */
private Visualization buildVisualization(Graph graph){
Visualization visualization = new Visualization();
visualization.add("graph", graph);
visualization.setRendererFactory(
new DefaultRendererFactory(this.getLabelRenderer())
);
visualization.putAction("color", this.getColor());
visualization.putAction("layout", this.getLayout());
visualization.run("color");
visualization.run("layout");
return visualization;
}
/**
* Recupera o renderizador de rótulos (labels)
* @return label renderer
* */
private LabelRenderer getLabelRenderer() {
if (this.labelRenderer == null) {
this.labelRenderer = new LabelRenderer("state");
this.labelRenderer.setRoundedCorner(8, 8);
}
return this.labelRenderer;
}
/**
* Recupera a paleta de cores a ser usada na renderização
* @return paleta de cores
* */
private int [] getColorPalette(){
return new int[] { ColorLib.rgb(255, 128, 128),
ColorLib.rgb(255, 128, 64), ColorLib.rgb(176, 176, 100),
ColorLib.rgb(100, 255, 64), ColorLib.rgb(128, 255, 255) };
}
public static void main(String[] args) throws DataIOException {
Visualizacao visualizacao = new Visualizacao();
JFrame frame = new JFrame("Grafo do Mapa do Brasil por Regiões");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(visualizacao.getDisplay());
frame.pack();
frame.setVisible(true);
}
}
Aqui, a informação para gerar o grafo apresentado é lida de um XML. Poderia ser muito bem carregada a partir de um banco de dados (interessante ler o metadata do banco para gerar relacionamento entre tabelas, não?). O código acima serve de boa base para você fazer sua própria aplicação. Creio que o prefuse seja uma opção bastante interessante em vez de usar tecnologias de visualização como Flash, onde você ainda teria o trabalho de fazer toda a integração, em vez de diretamente implementar listeners java.
E vocês, que APIs consideram interessantes para demonstrar o poder e em especial a simplicidade do Java?
ASSINE NOSSO RSS
Alberto Luiz
05. dez, 2006
Essa API é realmente muito boa, participo de um projeto no qual montamos a hierarquia de uma rede de computadores com o prefuse. No proprio vem com uns exemplos muito bons.
Alberto
Luiz Aguiar
05. dez, 2006
Caramba, muito legal isso ai hein…
bacana, parabéns.
ASOBrasil
06. dez, 2006
Não conhecia essa API, muito legal esse post. Parabéns!
Fernando Boaglio
12. dez, 2006
Legal, muito bom.
Para mostrar o poder do Java Desktop eu falo pra pessoa rodar o demo “SwingSet2″ que está dentro do diretório “demo” do JDK.
cd C:\jdk\demo\jfc\SwingSet2
java -jar SwingSet2.jar
Ivan
12. dez, 2006
Citei este seu texto no meu blog, mas não sei se o trackback funcionou como o esperado.
De qualquer maneira, parabéns pelo post!
Thadeu Russo
12. dez, 2006
Fico contente que gostaram do post
Espero estar mais tranquilo no ano que vem para escrever, pois me surgiram idéias muito legais e gostaria de compartilhas.
[]‘s a todos.
José Henrique
13. dez, 2006
Você poderia postar o seu XML que você usou no seu exemplo? Estou tentando reproduzir seu exemplo aqui, mas não tenho o XML para testar
Jean
21. jun, 2007
Estou tentando rodar o exemplo postado acima, mas não estou conseguindo, o que é necessário para rodar? Tb peguei o codigo do prefuse no site http://www.prefuse.org e não consigo abrir no netbeans como faço?
Thadeu
21. jun, 2007
Quando vc faz o download do site do prefuse, precisa compilar e gerar o jar. Coloque o jar no classpath e depois, eh so alegria
Wilma
08. jul, 2007
Também estou fazendo algumas pesquisas sobre o Prefuse mas estou com dificuldades em compílá-lo no NetBeans 5.5. Poderia me dar alguma dica?
Se possível, gostaria de receber também o arquivo XML do teste acima.
Agradeço.
Daniela
21. set, 2007
Olá
Gostaria de receber o XML do exemplo acima.
[]‘s
Fernando
07. out, 2007
Olá, vc é massa mesmo heim….
gostaria de uma dica, sobre grafo!!!!
Não consigo validar um código que faça um grafo de arvore geradora
de percurso minímo, pode me ajudar?
Oswaldo Castro
21. out, 2007
Belo trabalho Thadeu
Já estou com um monte de idéias para a utilização do prefuse (no site existe muita coisa também.
Parabéns mais uma vez
(Se possível também gostaria de obter o arquivo xml que Você usou. Pode ser?)
Abraços
Thadeu
22. out, 2007
Ola Oswaldo, teria como me pedir isso por email? thadeu.russo at caelum.com.br ?
Antonio Lazaro
30. abr, 2008
Belo post Tadheu, entretando hoje o site do prefuse não dispõe seus arquivos para download.
Você poderia me passar eles?
Hoje, você usaria prefuse ou flex para construções desses componentes complexos como árvores,grafos..?
Filipe Kovalski
18. fev, 2009
Link para o JNLP está quebrado =(
Thadeu
20. fev, 2009
Oi Filipe, corrigido.. Obrigado pelo aviso!
alberto
12. jul, 2009
Quero testar, mas preciso do arquivo XML, tem como postar?