17
Desenvolvimento de Aplicativos Desktop em Java Utilizando Padrões - T5 Seguir para... Prof. Antonio Passos DADP05 Recursos Artigo - Explorando e Customizando o JTable Artigo Java Magazine 42 - Componentes Avançados do Swing Componentes Avançados do Swing Parte 2: Explorando e Customizando o JTable Aprenda a customizar um dos mais poderosos e flexíveis componentes do Swing Esta é parte final de uma série que apresenta conceitos e exemplos sobre o uso e a customização de componentes Swing avançados. Na primeira parte, foi apresentado o componente JComboBox, além dos conceitos de modelos e cell renderers do Swing. Vimos também como reunir essas várias classes para formar um componente Swing customizado. Os exemplos foram baseados em um protótipo de aplicação de monitoração de rede, que exibe ícones específicos para os sistemas operacionais de cada host sendo monitorado, além de fazer uso de várias customizações visuais dos componentes. Esta segunda parte enfoca o componente JTable, utilizando o mesmo protótipo como exemplo. O JTable reutiliza algumas das classes do JComboBox e necessita de vários modelos e cell renderers especializados para lidar com a formatação de células, colunas e cabeçalhos. DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie... 1 de 17 07-08-2010 10:21

Artigo - Componentes Avançados do Swing

Embed Size (px)

Citation preview

Desenvolvimento de Aplicativos Desktop em JavaUtilizando Padrões - T5

◄ Seguir para... ►

Prof. Antonio Passos ► DADP05 ► Recursos ► Artigo - Explorando e Custom izando oJTable

Artigo Java Magazine 42 - Componentes Avançados do Swing

Componentes Avançados do SwingParte 2: Explorando e Customizando o JTable

Aprenda a customizar um dos mais poderosos e flexíveis componentes do Swing

Esta é parte final de uma série que apresenta conceitos e exemplos sobre o uso ea customização de componentes Swing avançados. Na primeira parte, foiapresentado o componente JComboBox, além dos conceitos de modelos e cellrenderers do Swing. Vimos também como reunir essas várias classes para formarum componente Swing customizado. Os exemplos foram baseados em umprotótipo de aplicação de monitoração de rede, que exibe ícones específicos paraos sistemas operacionais de cada host sendo monitorado, além de fazer uso devárias customizações visuais dos componentes.Esta segunda parte enfoca o componente JTable, utilizando o mesmo protótipocomo exemplo. O JTable reutiliza algumas das classes do JComboBox e necessitade vários modelos e cell renderers especializados para lidar com a formatação decélulas, colunas e cabeçalhos.

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

1 de 17 07-08-2010 10:21

Para mais detalhes sobre a arquitetura do Swing em geral e o relacionamento entrecomponentes e os vários tipos de classes que participam da sua implementação,consulte o quadro “Componentes e classes do Swing”. E no quadro “Dicas doNetBeans” apresentamos alguns recursos oferecidos por este IDE livre para auxiliarna customização de componentes pela criação de classes especializadas.

A tela de Hosts / JTableA tela de exemplo para esta segunda parte exibe uma relação de hosts,fornecendo informações como o sistema operacional, o endereço IP e o total dememória RAM. A relação de hosts será armazenada em uma coleção, maisespecificamente um List, cujo conteúdo será pré-fixado pelo código da aplicação.Para que o JTable seja capaz de exibir em linhas e colunas as informaçõescontidas nesta coleção, é necessário fornecer uma classe de modelo queimplementa a interface TableModel. A Listagem 1 apresenta a classe de modelocriada e a aplicação de testes. O resultado da sua execução pode ser visto naFigura 1.

HostTableModel.java

package jtable;import dados.Host;import dados.SistemaOperacional;import java.util.*;import javax.swing.table.*;public class HostTableModel extends AbstractTableModel { private List hosts; private String[] colunas = { "Nome", "Endereço IP", "S.O.", "RAM" }; public HostTableModel(List hosts) { super(); setHosts(hosts); } public int getColumnCount() { return 4; } public int getRowCount() { return hosts.size(); } public String getColumnName(int column) { return colunas[column]; } public Object getValueAt(int row, int column) { Host host = hosts.get(row); switch (column) { case 0: return host.getNome(); case 1: return host.getIp(); case 2:

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

2 de 17 07-08-2010 10:21

return host.getSo(); case 3: return host.getMemoriaRAM(); } return null; } public List getHosts() { return hosts; } public void setHosts(List hosts) { this.hosts = hosts; }}JanelaPrincipal.java

package jtable;import dados.Host;import java.util.*;import javax.swing.table.*;public class JanelaPrincipal extends javax.swing.JFrame { private List hosts = new ArrayList(); public JanelaPrincipal() { initComponents(); } public List getHosts() { return hosts; } public void setHosts(List hosts) { tabelaHosts.setModel(new HostTableModel(hosts)); } private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); tabelaHosts = new JTable(); setDefaultCloseOperation( javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle("Java Magazine - Demo do JTable"); jScrollPane1.setViewportView(tabelaHosts); getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER); pack(); } private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTable tabelaHosts; }Principal.java

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

3 de 17 07-08-2010 10:21

package jtable;import dados.Host;import dados.SistemaOperacional;import java.util.*;public class Principal { public static void main(String[] args) { List hosts = new ArrayList(); hosts.add(new Host("servidor", "192.168.0.1", SistemaOperacional.LINUX, 2048)); hosts.add(new Host("firewall", "192.168.0.2", SistemaOperacional.LINUX, 128)); hosts.add(new Host("contabilidade", "192.168.0.11",SistemaOperacional.WINDOWS, 256)); hosts.add(new Host("rh", "192.168.0.12", SistemaOperacional.WINDOWS, 512)); hosts.add(new Host("diretoria", "192.168.0.20", SistemaOperacional.WINDOWS,512)); hosts.add(new Host("marketing", "192.168.0.33", SistemaOperacional.MACOSX,1024)); JanelaPrincipal frame = new JanelaPrincipal(); frame.setHosts(hosts); frame.setVisible(true); } }

Figura 1. Primeira versão do exemplo de JTable

A classe de modelo do JTable (HostTableModel) faz o mínimo necessário paramapear as quatro propriedades da classe Host para as colunas da tabela. Detalhesvisuais como alinhamento à esquerda ou separadores de milhares em númerosnão são dependentes da classe de modelo (embora pudessem ser facilmenteimplementados nela). São dependentes da classe de visão, ou maisespecificamente, do respectivo cell renderer.Note que HostTableModel estende AbstractTableModel, e não DefaultTableModel.O motivo é evitar a necessidade de transformar a lista de hosts em um Vector deVectors de objetos, como esperado pelo DefaultTableModel. Com classes demodelo, ao contrário do que acontece com classes de cell renderers, em geral nãose estende a classe padrão.Os títulos das colunas são fornecidos pela própria classe de modelo. E asdimensões são calculadas automaticamente pelo JTable, que divide igualmente

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

4 de 17 07-08-2010 10:21

sua largura total entre elas.A classe Principal (no pacote jtable) cria uma lista de Hosts e inicializa a classeJanelaPrincipal (também em jtable) para usar essa lista. A classe JanelaPrincipal,ao receber a lista de hosts (método setHosts()) cria um HostsTableModel contendoesta lista. Todas as demais propriedades dos componentes ficam com seus valoresdefault.

Alguns IDEs, por exemplo o NetBeans, criam o componente JTable já vinculado a umanova instância do DefaultTableModel, que é criada pelo próprio IDE para definir colunas evalores iniciais para a tabela. Embora esta prática dê uma “sensação de programaçãovisual” mais forte ao JTable, ela interfere com o uso da classe de modelo customizada daaplicação. Por isso, no nosso caso, a classe de modelo gerada pelo IDE deve sereliminada.

Para chegar ao resultado visual desejado da tela de hosts, iremos passar por trêsetapas:

Melhorar a aparência das células da tabela, inserindo os ícones de sistemaoperacional e alinhando à direita a quantidade de memória RAM;

1.

Configurar as larguras corretas para as colunas;2.Melhorar a aparência dos cabeçalhos das colunas.3.

Para entender como obter estas melhorias, precisamos conhecer mais sobre aarquitetura do JTable.

Arquitetura do JTableUm JTable é formado por um conjunto de células (cells) e um cabeçalho (header).Ele reutiliza o ListSelectionModel do JList, mas define seus próprios modelos (umpara colunas e o cabeçalho; outro para os dados no corpo). Também define umtipo específico de cell renderer. A Figura 2 apresenta um diagrama de classes UMLcom sua arquitetura simplificada.

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

5 de 17 07-08-2010 10:21

Figura 2. Arquitetura simplificada do JTable do Swing. Foram omitidas as classesde visão do componente. Classes em amarelo são criadas especificamente para o

JTable, enquanto que as classes em rosa são reutilizadas de outros componentesSwing.

Caso se deseje formatar o número inteiro com separadores de milhares, deve-se criar umnovo TableCellRenderer, associado à classe Integer (ou então a Number), que utilizaum DecimalFormat (pacote java.text) para formatar o texto do JLabel.

Configurando as colunas do JTableA segunda etapa envolve definir as dimensões das colunas de acordo com ainformação apresentada em cada uma. A coluna “S.O.” só precisa ser larga osuficiente para exibir o ícone (e seu título, se este for mais largo que o ícone), e acoluna “RAM” necessita ter espaço para quatro ou cinco dígitos. A coluna “Nome”ocupa o restante da largura do componente.Calcular as larguras das colunas em função da largura do texto exige o uso daclasse java.awt.FontMetrics. Lembre que a fonte utilizada pela aplicação variaconforme a plataforma e o look-and-feel ativos, então não daria certo fixar adimensão em pixels.A Listagem 3 apresenta as modificações em HostJTable para obter o efeitodesejado. Agora são criadas manualmente várias instâncias de TableColumn, que

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

6 de 17 07-08-2010 10:21

são anexadas ao DefaultTableColunModel[1] herdado de JTable.

package jtable;//... imports omitidospublic class HostJTable extends JTable { FontMetrics fm; public HostJTable() { setAutoCreateColumnsFromModel(false); setAutoResizeMode(JTable.AUTO_RESIZE_OFF); } public void setHosts(List hosts) { //... aqui entra o conteúdo original do método setHosts() fm = getFontMetrics(getFont()); adicionaColuna(0, larguraEmLetras(30), "Nome", true); adicionaColuna(1, larguraEmDigitos(16), "Endereço IP", true); adicionaColuna(2, cellRenderer.getIconWidth(), "Sist.Oper.", false); adicionaColuna(3, larguraEmDigitos(5), "RAM", false); } private void recalculaLarguraDasColunas() { if (getColumnCount() == 0) return; TableColumn coluna; coluna = getColumnModel().getColumn(0); coluna.setWidth(larguraEmLetras(30)); coluna = getColumnModel().getColumn(1); coluna.setWidth(larguraEmDigitos(16)); coluna = getColumnModel().getColumn(2); coluna.setWidth(cellRenderer.getIconWidth()); coluna = getColumnModel().getColumn(3); coluna.setWidth(larguraEmDigitos(5)); } private void adicionaColuna(int indice, int largura, String titulo, boolean resizeable) { int larguraTitulo = fm.stringWidth(titulo + " "); if (largura < larguraTitulo) largura = larguraTitulo; TableColumn column = new TableColumn(indice, largura, null, null); column.setHeaderValue(titulo); column.setResizable(resizeable); column.setHeaderRenderer(headerRenderer); addColumn(column); }

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

7 de 17 07-08-2010 10:21

private int larguraEmLetras(int largura) { int letra = fm.stringWidth("M"); return largura * letra; } private int larguraEmDigitos(int largura) { int letra = fm.stringWidth("0"); return largura * letra; } public void setFont(Font font) { super.setFont(font); recalculaLarguraDasColunas(); }}Fica evidente o cálculo da largura das colunas em função da largura desejada e dalargura dos títulos (para evitar que um título longo seja cortado em uma colunaestreita) na criação do componente, mas o seu recálculo em setFont() não é tãoclaro. O motivo é que, se uma aplicação configurar uma fonte alternativa para ocomponente (que não seja o padrão do look-and-feel corrente), nada nos garanteque esta fonte será configurada antes ou depois da chamada a setHosts(). Se afonte for modificada depois de fornecida a lista de hosts, as larguras das colunaspoderão deixar ilegível parte dos títulos ou das próprias células.Agora que o componente customizado instancia seus próprios objetosTableColumn, o método getColumnName() e o atributo colunas de HostTableModelnão serão mais utilizados e podem ser deletados. Além disso, é necessáriogarantir que o JTable não irá criar automaticamente as colunas baseando-se noTableModel; por isso o construtor agora inclui a chamadasetAutoCreateColumnsFromModel(false).

Caso seja configurado um TableCellRenderer como parte do TableColumn, serãoignorados para esta coluna os TableCellRenderers associados a tipos de dados noJTable.

Desta vez, as larguras iniciais das colunas são pré-fixadas, então não desejamosque o JTable calcule as suas larguras. Por isto temos a chamada asetAutoResizeMode(JTable.AUTO_RESIZE_OFF) também no construtor.O resultado até o momento pode ser conferido na Figura 4.

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

8 de 17 07-08-2010 10:21

Figura 4. Tela de teste depois de configuradas as colunas do HostJTable

Caso se deseje que as colunas se auto-expandam para ocupar toda a largura da tabela, em

vez de deixar espaço vazio se a tabela for mais larga que suas células (ou uma barra de

rolagem caso ela seja mais estreita) deve-se manter a propriedade autoResizeMode com

o valor default e definir as propriedades maxWidth e minWidth das colunas que não se

deseja que sejam expandidas ou comprimidas.

Customizando os cabeçalhos do JTable

Finalizando este tutorial, vamos modificar a aparência dos cabeçalhos das colunas.

Para tal, deve ser associado um TableCellRenderer ao objeto TableColumn

correspondente. No exemplo será definido um único cell renderer chamado

MeuHeaderRenderer que configura as cores de frente e fundo do JLabel, dando

um maior destaque ao cabeçalho. Esta classe também alinha o título da quarta

coluna à direita, para que ele fique coerente com os valores numéricos da coluna.

O resultado final pode ser visto na Figura 5 e o código na Listagem 4.

MeuHederRenderer,java

package jtable;

//... imports omitidos

public class MeuHeaderRenderer extends DefaultTableCellRenderer {

public MeuHeaderRenderer() {}

public Component getTableCellRendererComponent(

javax.swing.JTable table, Object value,

boolean isSelected, boolean hasFocus, int row, int column)

{

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

9 de 17 07-08-2010 10:21

JLabel label = (JLabel)super.getTableCellRendererComponent(

table, value, isSelected, hasFocus, row, column);

label.setBorder(new LineBorder(Color.LIGHT_GRAY, 1));

label.setForeground(Color.LIGHT_GRAY);

label.setBackground(Color.DARK_GRAY);

if (column == 3)

label.setHorizontalAlignment(JLabel.RIGHT);

else

label.setHorizontalAlignment(JLabel.CENTER);

return label;

}

}

HostJTable.java

private MeuHeaderRenderer headerRenderer;

public void setHosts(List hosts) {

headerRenderer = new MeuHeaderRenderer();

//...

}

private void adicionaColuna(int indice, int largura, String titulo, boolean resizeable)

{

TableColumn column = new TableColumn(indice, largura, null, null);

column.setHeaderRenderer(headerRenderer);

//...

}

Figura 5. Resultado da terce ira etapa de custom ização sobre o JTable

Temos então um componente customizado, chamado HostJTable, cuja arquitetura

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

10 de 17 07-08-2010 10:21

é apresentada na Figura 6. É interessante comparar este diagrama com a Figura 6da primeira parte, que apresenta a arquitetura do SistemaOperacionalJComboBox,o componente criado sobre o JComboBox. Fica visível que, apesar do novocomponente JTable ter mais classes envolvidas, os dois componentescustomizados seguem a mesma arquitetura básica.

Figura 6. Arquitetura do componente custom izado HostJTable.

Conclusões

O uso dos componentes visuais do Swing é bem diferente dos componentes visuais

de IDEs RAD como Delphi e VB. No Swing, espera-se que o desenvolvedor escreva

código e crie novas classes para customizar o comportamento dos componentes,

em vez de se limitar à edição de propriedades.

A adaptação a esta nova filosofia de trabalho não é imediata, mas os resultados

compensam. No final das contas, uma aplicação Java com interface gráfica irá

conter uma grande quantidade de componentes customizados, e o benefício será

sentido pela reutilização de código. As próximas telas que necessitarem de

componentes semelhantes poderão ser construídas pela simples referências aos

componentes criados anteriormente, em vez de se repetir o processo manual de

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

11 de 17 07-08-2010 10:21

configuração das propriedades. Também ajuda o fato de que criar novoscomponentes em Java é muito mais simples do que em outros ambientes deprogramação visual.

Seria possível criar componentes genéricos com alguns dos recursos apresentados

neste tutorial, utilizando os recursos de reflexão do Java. Na verdade existem

projetos com esta proposta, como o SwingX e o SwingLabs do Java.Net (veja

referências), além de frameworks de desenvolvimento de aplicações visuais como

os fornecidos pela Plataforma NetBeans (não confundir com o IDE) e o JGoodies

Forms.

Infelizmente a maioria dos IDEs Java ainda não está bem adaptada à

customização de componentes pela criação de novas classes. Afinal eles não

podem seguir os modelos dos IDEs visuais não-Java, e com o foco da comunidade

Java ainda é maior na edição Enterprise, os esforços em termos de ferramentas

visuais deixaram a desejar. Mas a situação está mudando, como podemos ver por

exemplo nas últimas versões do NetBeans.

Para o leitor que deseja se aprofundar, o quadro “Para saber mais” no final do

artigo indica alguns artigos em edições anteriores da Java Magazine que falam

sobre desenvolvimento Swing e sobre o NeBeans.

Dicas do NetBeans

O NetBeans possui uma série de recursos que facilitam o desenvolvedor a lidar com

o código de customização de componentes Swing dentro do editor visual. Aqui

relacionamos alguns desses recursos:

l É possível substituir um componente Swing qualquer por uma subclasse,

entrando na aba “Code” das propriedades do componente e modificando a

propriedade “Custom Creation Code” (Figura Q2).

Figura Q2. Como trocar a classe de um componente padrão do Swing pela de um

componente custom izado

l O desenvolvedor que não gosta de “remendar” o método construtor das

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

12 de 17 07-08-2010 10:21

classes visuais, inserindo código após a chamada a initComponents() criada

pelo NetBeans, pode usar as propriedades “Post-Creation Code” e “Post-Init

Code”, que também podem ser vistas na Figura Q2.

l Todas as propriedades de qualquer componente permitem o acesso ao editor

de propriedades no modo “Form Connection” (Figura Q3) pelo botão de

reticências à direita do valor da propriedade.

Figura Q3. Configurando uma propriedade via código Java

Neste editor, está disponível o auto-completamento de código e o realce de

sintaxe, como no editor de código do NetBeans. Mas não são apontados

erros de sintaxe ou referências a identificadores não definidos, que só serão

apontados durante a compilação.

Ironicamente, um clique na mensagem de erro de compilação irá abrir o

editor de código do NetBeans na linha que contém o erro. Mas como ela foi

editada pelo editor visual, não será possível modificá-la (e corrigir o erro)

pelo editor de código.

l Caso o valor de uma propriedade tenha sido modificado inadvertidamente por

você (ou então pelo próprio IDE), é possível retornar ao seu valor default,

qualquer que seja ele, pelo menu de contexto (botão direito) da propriedade

(Figura Q4).

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

13 de 17 07-08-2010 10:21

Figura Q4. Retornando uma propriedade de um componente ao seu valor default

O efeito é eliminar, do código gerado pelo editor visual, a chamada a

setNomeDaPropriedade(), de modo que nem o IDE nem o usuário necessita

saber qual seria o valor default.

Vale a pena lembrar que as propriedades que foram modificadas são

destacadas em negrito na janela de propriedades do editor visual.

Componentes e classes do Swing

Para entender o uso correto de recursos avançados do Swing, é importante ter

claros os conceitos de classe e componente no Java. Um componente JavaBean,

segundo a especificação JavaBeans, é “um componente reusável que pode ser

manipulado visualmente por uma ferramenta de desenvolvimento”. Poucas vezes é viável

inserir toda a funcionalidade requerida por um componente dentro de uma única

classe; por isso a classe que o desenvolvedor normalmente identifica como sendo

um “componente” é apenas aquela que coordena o trabalho de várias outras para

fornecer a funcionalidade desejada.

As classes que representam objetos visuais do Swing, como javax.swing.JLabel,

javax.swing.JComboBox e javax.swing.JTable, na verdade são os “controladores”

destes componentes, dentro da arquitetura MVC (Modelo-Visão-Controlador).

Componentes simples como um JButton podem necessitar apenas das respectivas

classes de visão e de modelo (no caso, javax.swing.plaf.ButtonUI e

javax.swing.ButtonModel). Mas componentes complexos como um JTable utilizam

uma série de outras classes de apoio[1], chegando neste caso a existir um pacote

separado javax.swing.table, apenas para abrigar essas classes.

A adoção da arquitetura MVC pelo Swing (veja a Figura Q1) permite que

componentes sejam adaptados a práticas de orientação a objetos predominantes,

pois o uso de classes de modelo permite que várias estruturas de dados diferentes

sejam suportadas pelos componentes. O desenvolvedor não fica limitado, por

exemplo, ao uso de bancos de dados relacionais como acontece com alguns

componentes “data-aware” de ambientes como Delphi e VB.

O uso de MVC pelo Swing também permite que os componentes suportem

múltiplas aparências, com uma flexibilidade sem precedentes em qualquer outro

ambiente. Na verdade, pacotes de look-and-feels alternativos, como o TinyLAF e o

JGoodies Looks (veja links), fornecem justamente classes de visão alternativas

para os componentes do Swing.

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

14 de 17 07-08-2010 10:21

Um detalhe importante é que muitos dos componentes do Swing esperam que o

desenvolvedor crie suas próprias classes de modelo. Ao contrário do que acontece

em outros ambientes, onde todos os dados são reduzidos a strings e números

para exibição e edição pelos componentes visuais, o Swing espera lidar com os

próprios objetos de domínio da aplicação.

No caso de componentes que representam apenas dados simples, por exemplo

JCheckBox, JLabel ou um JTextField (ou mesmo um JFormattedTextField), as

classes de modelo padrão do Swing serão suficientes para o desenvolvedor, que

nem irá tomar conhecimento de sua existência.

Mas a situação muda quando se utilizam componentes que representam coleções

de valores, como um JList, JComboBox ou JTree, ou de componentes que

permitem a visualização de várias propriedades de um mesmo objeto, como um

JTable. Nestes casos, é essencial a criação de classes de modelo para fazer o

mapeamento entre as propriedades dos objetos e a sua exibição visual pelo

componente.

Quanto mais complexo o componente, menor a utilidade das classes de modelo padrão do

Swing, como DefaultTableModel. Isto porque o uso destas classes exige a conversão dos

dados do modelo de dados da aplicação para o modelo do Swing. O consumo de memória e

o tempo de processamento podem ser significativos.

Figura Q1. Uso da arquitetura MVC pelo Swing, exemplificado pelo componente

JButton

O desenvolvedor vindo de ambientes visuais como o Delphi ou o VB espera

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

15 de 17 07-08-2010 10:21

customizar todo o comportamento dos componentes visuais pela simples edição depropriedades. Se algo não pode ser feito por meio delas, o desenvolvedor buscaum outro componente no mercado que tenha a opção desejada, ou considera quea customização seja impossível. Mas os componentes Swing esperam sercustomizados pela substituição ou especialização dos seus objetos de apoio. OSwing define inúmeras interfaces e classes abstratas com este propósito. Oresultado é que, para tirar proveito de todo o potencial do Swing, o desenvolvedorprecisará sair do editor visual de interfaces e voltar ao editor de código.

O foco do Swing em código e design patterns em vez da definição visual por meio

de propriedades gera a fama de “difícil” Java no desktop em relação a outras

ferramentas de desenvolvimento visuais. Por outro lado, traz o benefício de que o

desenvolvedor não fica preso aos recursos de um IDE em particular. É possível

migrar o código para outro IDE sem necessidade de retrabalho; ou até mesmo

mesclar componentes construídos em diferentes IDEs.

Para Saber Mais

Componentes Avançados do Swing, Fernando Lozano, Ed. 41

Apresenta a custom ização de um componente JComboBox e os conceitos de

models e renderes do Swing

Explorando o NetBeans 5, Fernando Lozano, Ed. 32

Descreve os novos recursos de edição visual de interfaces do NetBeans 5, através

de uma aplicação completa

Aplicação Completa com NetBeans, Fernando Lozano, Ed. 25, 26 e 27

Descreve passo a passo a construção de uma aplicação de “Lista de Tarefas”

usando os recursos do NetBeans e o banco de dados HSQLDB

Datas com Swing, Fernando Lozano, Ed. 28

Descreve o uso dos componentes do NachoCalendar para Swing, inclusive como

adiciona-los ao pallete do Eclipse VE e do NetBeans

Formulários com Swing, Bruno Souza, Ed.14

Explica os conceitos re lacionados com os Layout Managers do AWT/Swing

Links

java.sun.com/docs/books/tutorial/uiswing/components

Trilha do Java Tutoria l sobre componentes Swing

muntjak.de/hans/java/tinylaf

Página oficia l do TinyLAF

jgoodies.dev.java.net

Página oficia l do JGoodies

napkinlaf.sf.net

Página oficia l do Napkin LAF

swinglabs.org

Página oficia l do SwingX, conjunto de componentes custom izados para Swing

netbeans.org

Página oficia l do NetBeans IDE e da Plataforma NetBeans

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

16 de 17 07-08-2010 10:21

[1] No código estamos supondo que o ícone sempre será mais a lto do que a fontede texto do componente, o que poderá não ser verdade em algum LAFcustom izado, ou caso o usuário custom ize o seu tema de área de trabalho parausar fontes muito grandes.[2] O método addColumn() de JTable delega para o método correspondente emTableColumnModel, que por default é uma instância de DefaultTableColumnModel[3] O le itor com conhecimento de design patterns irá reconhecer vários outrospadrões além do MVC na implementação dos componentes do Swing,especialmente Facade, Adaptor, Delegate e Strategy. Mas, para tornar esta sériemais simples para o iniciantes, om itimos a apresentação formal destes designpatterns.

Última atualização: domingo, 22 novembro 2009, 10:03

Você acessou como Henrique de Pontes R ibe iro (Sair)

DADP05: Artigo - Explorando e Customizando o JTable http://www.antoniopassos.net/ead/mod/resource/vie...

17 de 17 07-08-2010 10:21