Travar edição de uma derminada célula no JTable

Caros Colegas,

Boa tarde,

Estou tentando fazer com que uma determinada célula do Jtable trave a edição de acordo com o contéudo escolhido em uma célula anterior.

Exemplo:

Célula 1 = é um combobox com opções[] = {“Automatico”,“Manual”};

Gostaria que no momento em que o usuário estivesse digitando os dados na tabela, se ele escolhesse a opção automatico, o sistema bloquearia a celula 2 e 3, habilitando somente a 4. Caso contrário, habilitaria a celula 4 e desabilitaria a edição nas células 2 e 3.

Estava pensando em utilizar o método:

public boolean isCellEditable(int rowIndex, int columnIndex)

Mas o mesmo bloqueia a coluna por completo.

Agradeço-lhes antecipadamente.

Atenciosamente,

Amarildo

Amarildo,

Para a tabela funcionar da maneira que queres, é necessário que tu defina e use na tabela um TableModel específico. Basta implementar a interface TableModel. Não é difícil, há inúmeros exemplos de como fazer isto na documentação: http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#data

Obs.: o método isCellEditable(int rowIndex, int columnIndex) define se é possível a edição de cada célula, e não da coluna inteira! Possivelmente houve algum erro na tua implementação.

Bruno

Bruno,

Primeiramente obrigado pela resposta,

Sou iniciante em Java. Já olhei e procurei em toda a documentação do Java, mas não consigo estou implementando meu próprio TableModel realmente, mas não sei como fazer isso dentro dele.

jtbmov.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null}
},
new String [] {
“Conta”, “Tipo”, “Vr.PA”, “Vr.PR”, “Vr.Geral”
}
) {
Class[] types = new Class [] {
java.lang.Object.class, java.lang.Object.class, java.lang.Double.class, java.lang.Double.class, java.lang.Double.class
};
boolean[] canEdit = new boolean [] {
true, true, false, false, true
};

        public Class getColumnClass(int columnIndex) {
            return types [columnIndex];
        }

        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return canEdit [columnIndex];
        }
    });

As células da coluna Vr.Pa e Vr.PR devem ser habilitadas a edição somente se o conteúdo da célula Tipo for = “Manual”.

Se alguém tiver demais formas de fazer isso, agradeço muito.

Amarildo

Olha, dê uma lida na página que eu indiquei no primeiro post. O que tu precisa fazer é um pouco grande demais para ser resolvido da forma como mostrasse.

Faça uma classe que implementa TableModel, e use-a como modelo da tua tabela. A interface TableModel define todos os métodos necessários para definir o comportamento da tabela! Basta implementá-los!

class AmarildoTableModel implements TableModel { //aqui tu vais implementar todos os métodos definidos na interface TableModel }

e no local específico:

Amigo,

Muito obrigado, vou tentar implementar agora.

Amarildo

Olá Pessoal,

Bom dia,

Realmente não consigo fazer isso funcionar, se alguém tivar alguma outra solução, ficarei muito agradecido.

Sds

Amarildo

 public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}

Esse método vai bloquear a coluna para todas as linhas, pois, não importa a linha, ele vai bloquear a coluna.
O array canEdit deveria ter a linha tb.

Quanto a implementar o seu propio TableModel, concordo, é o melhor, pois o que vc está fazendo é implementar o TableModel na hora, o bom é ter uma classe pronta externa para utilizar.

Implemneta tb um método publico para setar a coluna e linha que quer bloquear no TableModel, assim vc irá validar a celula na JTable e setar no TableModel que a linha e coluna X,Y não podera ser editada.
Essa validação deve ser feita num StopEditing da vida.

Essa parte pra criar um TableModel é complicada devido a complexidade, mas uma vez criado, vc pode utilizar em qqer JTable :slight_smile:

Pois é rapaiz,

Obrigado ai.

Criei uma classe MyTableModel extendida de AbastracTableModel :

class MyTableModel extends AbstractTableModel {
String[] colunas = {“Conta”, “Tipo”, “Vr.PA”, “Vr.PR”, “Vr.Geral”};
Object[][] linhas = {
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null},
{null, null, null, null, null}
};

    public int getRowCount() {
        return linhas.length;
    }
    
    Class[] types = new Class [] {
            java.lang.Object.class, java.lang.String.class, java.lang.Double.class, java.lang.Double.class, java.lang.Double.class
        };
    
    public Class getColumnClass(int columnIndex) {
            return types [columnIndex];
        }
    
    public String getColumnName(int col) {
        return colunas[col];
    }

    boolean[] canEdit = new boolean[] {
        true,true,false,false,true
    };
    
    public int getColumnCount() {
        return colunas.length;
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        return linhas[rowIndex][columnIndex];
    }
    
    public boolean isCellEditable(int row, int col) {
        return canEdit[col];
    }
    
    public void setValueAt(Object value, int row, int col) {
        linhas[row][col] = value;
    }
    
 }

após criar tal classe estou tentando adicionar um listener nela, mas não consigo, estou utilizando o seguinte código:

   tabela.setModel(new MyTableModel());
   tabela.getModel().addTableModelListener(new TableModelListener() {
       public void tableChanged(TableModelEvent e) {
           int row = e.getLastRow();
           int col = e.getColumn();
           System.out.println("Teste : "+col);
       }
   }); 

Mas, quando clico ou altero o conteúdo da tabela, não me mostra nenhuma msg. Sei que se conseguir fazer isso conseguirei resolver meu problema aqui.

Obrigado

Pessoal,

Consegui fazer uma classe para verificar as alterações na tabela.
Quando vc muda algum dado na tabela, a mesma é atualizada, porém seu tablemodel não, no entanto vc deve usar o método fireTableCellUpdated(row, col); para isto e assim o sistema “entender” que houve uma alteração.

Sds

Amarildo