Projeto Towel: AutoFiltro em JTable

Valew Marky. Vou estuda-lo. :smiley:

É que largura de coluna é uma informação de view, não de model. O model trata dos dados. Por isso, você define largura de colunas usando o próprio objeto JTable. :wink:

Ah ta, eu entendi. Eu adaptei a classe q o Marky me passou e funcionou perfeitamente.
Muito Obrigado.

Bom dia a todos. Vini estou com um caso assim. Quando eu abro uma cosulta no banco de dados, eu ja do um select * na tabela do banco que eu quero os dados e jogo no meu jtable com seu model.
Dai eu to na duvida: se eu for selecionar uma linha para restaurar os dados da table para o formulario de apresentação, eu preciso fazer um outro select no banco ou tem como eu aproveitar os dados que ja foram localizados e estao em no list que eu joguei no seu modelo? - Para nao usar o getValueAt, pois nao tenho todos os atributos no table.

Daí, eu pensei q já q eu ja tinha feito um select e estava com todos os dados ali na aplicação nao seria necessario refazer um novo select filtrando, mas sim filtrar na aplicação. (Sendo q antes eu fazia isso, pois era mais facil).

Eu lembrei q vc citou q esse modelo nao precisa utilizar o metodo getValueAt, sendo assim, como utilizar seu modelo para resolver essa questão?

obrigado.

Tem sim. Basta você pegar os dados a partir do seu TableModel.

O auto-filtro tem um método que, baseado num valor selecionado da view, ele retorna a linha correspondente no model que está associado a ele. Você usa esse método e então pede pro TableModel o objeto, usando o método get.

Ah eh verdade, eu nem lembrava q ele ja fazia isso…rsrsrsrs… Esse auto filtro eh mto bom hein… foi vc q desenvolveu ele tbm??
mto obrigado.

[quote=caceres]Ah eh verdade, eu nem lembrava q ele ja fazia isso…rsrsrsrs… Esse auto filtro eh mto bom hein… foi vc q desenvolveu ele tbm??
mto obrigado.[/quote]

Sim. Eu desenvolvi o auto-filtro e o ColumnTableModel. Na verdade, não desenvolvi sozinho. Um colega do trabalho, o pnizer do fórum, desenvolveu comigo. Ele desenvolveu a primeira versão praticamente sozinho.

Quando começou a dar uns problemas, nós refizemos o filtro todo juntos (em pair programming). Não foi só um refactoring. Efetivamente sentamos, estudamos o conceito e remodelamos a classe inteira.

Deu um trabalhão, mas o resultado final ficou muito bacana.

O ColumnTableModel é autoria minha mesmo. Embora outro colega de trabalho, o anlugifa do fórum, também tivesse algo muito parecido nos projetos dele. Como o Column estava um pouco mais completo, nós só completamentamos com o que faltava, refatoramos para deixar um pouco mais flexível, e então chegamos a essa versão final.

Parabens, excelente trabalho. Obrigado.

Boa noite.

Vini, vc poderia exemplificar esses metodos… eu verifiquei todos os metodos q existe na classe TableFilter mas nao consegui uma logica para montar isso…

de inicio eu observei q tem os metodos q pegam a linha ou coluna editavel, mas eu nao sei qual eh q faz isso.

te juro q tentei mto… olha a hora q eu postei aqui…rsrsrsrs…

se puder me ajudar, agradeço mto…

Você vai fazer mais ou menos assim:

[code]//Pega a linha da tabela selecionada.
//É a linha na view, não no model, pois pode estar filtrado
int vwSelected = suaTable.getSelectedRow();

//Obtém o índice dessa linha no model
int mdlSelected = tableFilter.getModelRow(vwSelected);

//Pede para o model o objeto que está naquela linha
SeuObjeto obj = seuTableModel.get(mdlSelected);

//Chama seu método que copia os dados do objeto
//para os JTextFields, JComboBoxes, etc…
preencherCampos(obj);[/code]

Além do getModelRow, existe também o método getModelRows. É útil para, por exemplo, quando você quiser excluir todas as linhas que estão selecionadas.

Rapaiz do céu, o negócio fico bunito d+…hehehhe…
Era tão simples e eu tava complicando…
Eu praticamente tava tentando fazer do zero (reinventar a roda - como se diz).
Eu tava pegando o list e jogando ele num outro list (para não perder os dados), e depois tentava filtrar, mais tava meio feio a coisa…

valew ae Vini… abração

Vini, esse exemple que vc deu ai pra fazer o FIlter da pra rodar pegando os dados vindos do banco?

Abri ele aki no netbeans e ve q tem outras class, qual q class principal pra o filtro?

habinovich, voce nao deveria se preocupar de onde os dados vem, e sim em como eles vão para na JTable, voce precisa estudar sobre o TableModel.

Eu consigo pegar os dados mas n consigo e filtra-los usando uma JtextField, para deixar na tabela so os dados q forem digitados neles!

Olá Vini,

Eu estava olhando a implementação do seu ColumnTableModel e não consegui entender qual a utilidade dos seguintes métodos:

public static <K, V> ColumnTableModel<Map.Entry<K, V>> createMapModel(Map<K, V> map, String keyHeader, String valueHeader)

public static void applyToTable(JTable table, List< ? extends Column< ? >> columns)

Poderia explicá-lo um pouco mais além do descrito nos comentários? Principalmente o applyToTable(), pois eu estou querendo renderizar componentes(como um JButton e um ComboBox) numa coluna e este método me parece ser o responsável por setar o Renderer e o Editor.

Eu implementei um exemplo, usando a interface EditableColumn, e consegui renderizar um JButton, porém, não sei se foi da forma correta, por dois motivos:
1º)Na minha classe de negocio(Pessoa) eu criei um atributo do tipo JButton e lá tem o método getBotao…muito estranho misturar atributos de negocio e um botão com uma ação de detalhe não acha?(rsrs)
2º)Na interface EditableColumn tem o método getEditor()(que retorna um TableCellEditor) e tem por extends o método getRenderer()(que retorna um TableCellRenderer), mas eu não os utilizei para renderizar o JButton eu deveria usa-los? E onde eles são chamados?

Eu consegui resolver a minha necessidade, mas não sei se da melhor maneira, entende. Tem alguma dica?

Obrigado pela atenção.

Abraços

Ola Vini, você poderia postar um exemplo simples de como implementar a classe EditableColumn (ao invés de Column)?

Estou em duvida como implementar o método public TableCellEditor getEditor().

Oi. Posso sim, mas no final de semana.

Lintz, desculpe não te responder. O GUJ não me enviou um e-mail com a sua dúvida, só vi hoje. Você ainda precisa disso?

Segue um exemplo:


package pessoaSimple;


public class Pessoa {
	private Integer id;
	private String nome;
	private String rg;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
	public String getRg() {
		return rg;
	}
	public void setRg(String rg) {
		this.rg = rg;
	}

}
package pessoaSimple;

import javax.swing.JButton;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

import util.gui.table.EditableColumn;
import util.gui.table.UtilTableCellRenderer;

public enum PessoaColumns implements EditableColumn<Pessoa>{
	ID("Id") {   
        //Esse método precisa retornar para o table o ID da pessoa   
        public Object getValue(Pessoa p)   
        {   
            return p.getId();   
        }

    },   
    NOME("Nome") {   
        public Object getValue(Pessoa p)   
        {   
            return p.getNome();   
        }  
        public boolean isEditable(Pessoa p){
        	return true;
        }

    },   
    RG("R.G.")  {   
        public Object getValue(Pessoa p)   
        {   
            return p.getRg();   
        } 
        public boolean isEditable(Pessoa p){
        	return true;
        }
    };   
  
   private final String nome;
   
   //Daqui para baixo, são configurações que valem para todas as colunas
   private PessoaColumns(String nome) {   
      this.nome = nome;   
   }   
  
   public Class< ? > getColumnClass() {   
        return Object.class;   
   }   
  
    public String getName() {   
        return nome;   
    }   
  
    public TableCellRenderer getRenderer() {   
        return null;   
    }   
    
    public TableCellEditor getEditor(){
    	return null;
    }
  
    public int getModelIndex() {   
        return ordinal();   
    }   
  
    public int getWidth() {   
        return 300;   
    }   
    
    public boolean isEditable(Pessoa p){
    	return false;
    }
    
    public void setValue(Pessoa object, Object value){
    	
    }
    
}
package pessoaSimple;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;

import util.gui.table.ColumnTableModel;
import util.gui.table.UtilTableCellRenderer;

public class PessoaSample extends JFrame {


    private static final long serialVersionUID = 1L;
    private JPanel jContentPane = null;
    private JPanel pnlButtons = null;
    private JButton btnAdd = null;
    private JButton btnRemove = null;
    private JButton btnClose = null;
    private JScrollPane scrlTable = null;
    private JTable tblPessoa = null;
   // private TableFilter tableFilter;
    private ColumnTableModel<Pessoa> tableModel;

    public PessoaSample() {
        super();
        initialize();
    }

    private void initialize() {
        this.setSize(453, 304);
        this.setContentPane(getJContentPane());
        this.setTitle("JFrame");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private JPanel getJContentPane() {
        if (jContentPane == null) {
            jContentPane = new JPanel();
            jContentPane.setLayout(new BorderLayout());
            jContentPane.add(getPnlButtons(), BorderLayout.SOUTH);
            jContentPane.add(getScrlTable(), BorderLayout.CENTER);
        }
        return jContentPane;
    }

    private JPanel getPnlButtons() {
        if (pnlButtons == null) {
            pnlButtons = new JPanel();
            pnlButtons.setLayout(new FlowLayout());
            pnlButtons.add(getBtnAdd(), null);
            pnlButtons.add(getBtnRemove(), null);
            pnlButtons.add(getBtnClose(), null);
        }
        return pnlButtons;
    }

    private JButton getBtnAdd() {
        if (btnAdd == null) {
            btnAdd = new JButton();
            btnAdd.setText("Add");
            btnAdd.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    onAdd();
                }
            });
        }
        return btnAdd;
    }

    private JButton getBtnRemove() {
        if (btnRemove == null) {
            btnRemove = new JButton();
            btnRemove.setText("Remove");
            btnRemove.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    onRemove();
                }
            });
        }
        return btnRemove;
    }

    private JButton getBtnClose() {
        if (btnClose == null) {
            btnClose = new JButton();
            btnClose.setText("Close");
            btnClose.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent e) {
                    System.exit(0);
                }
            });
        }
        return btnClose;
    }

    private JScrollPane getScrlTable() {
        if (scrlTable == null) {
            scrlTable = new JScrollPane();
            scrlTable.setViewportView(getTblPessoa());
        }
        return scrlTable;
    }

    private JTable getTblPessoa() {
        if (tblPessoa == null) {
        	tblPessoa = new JTable();
            // Associe sua tabela ao table filter DEPOIS de cria-la
          //  tblString.setModel(getStringTableFilter());
        	tblPessoa.setModel(getPessoaTableModel());
        	
        	tblPessoa.setDefaultRenderer(JButton.class, UtilTableCellRenderer.getButtonRenderer());
        	tblPessoa.setDefaultEditor(JButton.class,  UtilTableCellRenderer.getButtonEditor());
        }
        return tblPessoa;
    }

     /**
     * Retorna o table model.
     */
    private ColumnTableModel<Pessoa> getPessoaTableModel() {
        if (tableModel == null) {
            // Esse model se comporta como um arraylist! :)
            tableModel = new ColumnTableModel<Pessoa>(PessoaColumns.values());
            ColumnTableModel.applyToTable(tblPessoa, PessoaColumns.values());
        }
        return tableModel;
    }

    private void onRemove() {
        if (getTblPessoa().getSelectedRowCount() == 0)
            return;

        // Precisamos traduzir as linhas que estamos vendo, para as linhas que
        // estão no
        // modelo. Fazemos isso usando esse método.
       // int[] modelRows = getStringTableFilter().getModelRows(
       //         getTblString().getSelectedRows());

        // Já fornecemos um método conveniente para esse tipo de remoção.
        getPessoaTableModel().remove(getTblPessoa().getSelectedRow());
    }

    private void onAdd() {
        String valueId= JOptionPane.showInputDialog("Entre com um id");
        if (valueId == null)
            return;
        
        String valueNome = JOptionPane.showInputDialog("Entre com um nome");
        if (valueNome == null)
            return;
        
        String valueRg = JOptionPane.showInputDialog("Entre com um RG");
        if (valueRg == null)
            return;
        
        Pessoa pessoa = new Pessoa();
        pessoa.setId(new Integer(valueId));
        
        pessoa.setNome(valueNome.toString());
        pessoa.setRg(valueRg.toString());
        
        pessoa.setAcao(new JButton());
        
        // Simplesmente adicionamos no model.
        getPessoaTableModel().add(pessoa);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new PessoaSample().setVisible(true);
            }
        });
    }


}

[quote=ViniGodoy]Oi. Posso sim, mas no final de semana.

Lintz, desculpe não te responder. O GUJ não me enviou um e-mail com a sua dúvida, só vi hoje. Você ainda precisa disso?[/quote]

Oi Vini,

Eu já descobri… mas valeu.

Abraços

Bom dia a todos.
É o meu primeiro post, espero que possa postar mais vezes.

Tenho uma dúvida, Marky e ViniGodoy vocês que são mais experientes usam hibernate com estes table models para popular a tabel?
Caso outras pessoas se interessarem, podem responder também, ficaria grato.

[quote=ViniGodoy]Oi. Posso sim, mas no final de semana.

Lintz, desculpe não te responder. O GUJ não me enviou um e-mail com a sua dúvida, só vi hoje. Você ainda precisa disso?[/quote]