JTable mantendo a seleção de várias linhas

4 respostas
Joao.Gabriel

Pessoal,

Estou com um problema para definir um comportamento específico em Swing.

Tenho um JTable e preciso que, ao selecionar uma nova linha, ele mantenha todas as anteriores selecionadas também.

Basicamente, o comportamento que preciso é o mesmo de um Ctrl + Clique.

Segue a imagem de como deveria ficar a seleção:

[URL=http://imageshack.us/photo/my-images/594/tabelan.png/][/URL]

Vejam que preciso manter, para cada linha selecionada pelo usuário, um background na cor azul.

A minha classe usada para testes hoje está assim:

public class TesteSelecao {
     
      public TesteSelecao() {
            JFrame frame = new JFrame("Table");
 
            frame.addWindowListener(new WindowAdapter() {
                  public void windowClosing(WindowEvent e) {
                        System.exit(0);
                  }
            });
 
            // Take the dummy data from SwingSet.
            final String[] names = { "First Name", "Last Name", "Favorite Color", "Favorite Number", "Vegetarian" };
            final Object[][] data = {
                        { "Tom", "Ball", "Blue", new Integer(99), new Boolean(false) },
                        { "Alan", "Chung", "Green", new Integer(838), new Boolean(false) },
                        { "Amy", "Fowler", "Yellow", new Integer(3), new Boolean(false) },
                        { "Brian", "Gerhold", "Green", new Integer(0), new Boolean(false) },
                        { "James", "Gosling", "Pink", new Integer(21), new Boolean(false) },
                        { "David", "Karlton", "Red", new Integer(1), new Boolean(false) },
                        { "Dave", "Kloba", "Yellow", new Integer(14), new Boolean(false) },
                        { "Peter", "Korn", "Purple", new Integer(12), new Boolean(false) },
                        { "Phil", "Milne", "Purple", new Integer(3), new Boolean(false) },
                        { "Dave", "Moore", "Green", new Integer(88), new Boolean(false) },
                        { "Hans", "Muller", "Maroon", new Integer(5), new Boolean(false) },
                        { "Rick", "Levenson", "Blue", new Integer(2), new Boolean(false) },
                        { "Tim", "Prinzing", "Blue", new Integer(22), new Boolean(false) },
                        { "Chester", "Rose", "Black", new Integer(0), new Boolean(false) },
                        { "Ray", "Ryan", "Gray", new Integer(77), new Boolean(false) },
                        { "Georges", "Saab", "Red", new Integer(4), new Boolean(false) },
                        { "Willie", "Walker", "Phthalo Blue", new Integer(4), new Boolean(false) },
                        { "Kathy", "Walrath", "Blue", new Integer(8), new Boolean(false) },
                        { "Arnaud", "Weber", "Green", new Integer(44), new Boolean(false) } };
 
            TableModel dataModel = new AbstractTableModel() {
                  public int getColumnCount() {
                        return names.length;
                  }
 
                  public int getRowCount() {
                        return data.length;
                  }
 
                  public Object getValueAt(int row, int col) {
                        return data[row][col];
                  }
 
                  public String getColumnName(int column) {
                        return names[column];
                  }
 
                  public Class getColumnClass(int col) {
                        return getValueAt(0, col).getClass();
                  }
 
                  public boolean isCellEditable(int row, int col) {
                        return (col == 4);
                  }
 
                  public void setValueAt(Object aValue, int row, int column) {
                        data[row][column] = aValue;
                  }
            };
 
            JTable table = new JTable(dataModel);
            table.setRowSelectionAllowed(true);
            table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 
            JScrollPane scrollpane = new JScrollPane(table);
            scrollpane.setPreferredSize(new Dimension(700, 300));
 
            frame.getContentPane().add(scrollpane);
            frame.pack();
            frame.setVisible(true);
      }
 
      public static void main(String[] args) {
            new TesteSelecao();
      }
     
}

Preciso da ajuda de vocês, qual seria a melhor forma de implementar esse comportamento?

Obrigado!

4 Respostas

Eric_Yuzo

Neste tipo de situação eu prefiro deixar um campo com um checkbox para definir quais linhas estão ou não marcadas.

Não gosto muito de modificar comportamentos que já são considerados um “padrão” em grande parte dos softwares, como o Ctrl + clique para seleção múltipla.

Mas se precisar mesmo deste comportamento, pode conseguí-lo sobrescrevendo o método changeSelection:

table = new JTable() { @Override public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) { super.changeSelection(rowIndex, columnIndex, !extend, extend); }; };
Outra coisa, procure implementar o seu TableModel para guardar uma lista de objetos do seu domínio ao invés de um array de Object[].

R_chieck

Ola, geralmente numa jTable caso vc não especifique o modo de seleção e permite selecionar multiplas linhas. Tente isso.
Concordo com oque o Eric Yuzo disse, implemente seu proprio TableModel, o default está condenado e ja é quase obsoleto.
Caso não queira implementar o seu , ao menos procure na internet que podes achar pronto um ObjectTableModel. flw

Joao.Gabriel

Ok galera, vou dar uma olhada no changeSelection.

Mas quanto ao array, vejam que se trata apenas de uma classe de teste. Serve apenas para isso. O projeto de fato usa TableModel.

Att.

Joao.Gabriel

Ok Eric, funcionou. Obrigado pela ajuda!

Fiz apenas uma pequena alteração, deixando assim:

table = new JTable() {  
        @Override  
        public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {  
            super.changeSelection(rowIndex, columnIndex, true, extend);  
        };  
    };

A ideia é não perder o comportamento padrão quando o Ctrl é utilizado.

Concordo com vocês que essa funcionalidade não é a ideal, mas requisitos são requisitos… :lol:

Valeu!

Criado 26 de julho de 2011
Ultima resposta 27 de jul. de 2011
Respostas 4
Participantes 3