Somente números célula JTable

Olá.

Alguém saberia como implementar um Key Listener em uma determinada coluna de um JTable para que a mesma só aceite números. Gostaria que automaticamente o sistema bloqueasse as teclas que não são números.

Boa noite Blst.

Voce não precisa criar um listener de evento qualquer para fazer isto.

O JTable permite que voce adicione máscaras desta forma:

        .....
        MaskFormatter msk = null;
        try {
           msk = new MaskFormatter("(##) ####-####");
           msk.setPlaceholder("_");
        } catch (Exception ex){
           JOptionPane.showMessageDialog(this, "Erro na criação de máscara no JTable");
        }
        JFormattedTextField jftf = new JFormattedTextField(msk);
        jtable.getColumnModel().getColumn(4).setCellEditor(new DefaultCellEditor(jftf));
        ....

No caso acima, eu formatei a quinta coluna (getColumn(4)) para receber somente números de telefone, ao digitar qualquer caracter diferente de número, ele não permite inserir no coluna 4 do JTable

Então discorpio, também pensei em fazer dessa maneira.

Porém, eu já seto um CellEditor para as minhas colunas do JTable para manipular os dados da tabela.

Por exemplo, no meu caso estou fazendo um pedido de vendas. O usuário incluirá o código do produto na primeira coluna. Automaticamente o sistema trará na segunda coluna o valor do produto. (Isso eu já faço utilizando um AbstractCellEditor, no qual eu seto no cellEditor da coluna).
O que eu gostaria de fazer agora é setar a coluna qtde com somente números, porém, ela também utiliza a classe que eu criei com o AbstractCellEditor para que ao usuário digitar a quantidade, o sistema já traga o valor total.

Não sei se fui muito claro, mas a minha dúvida é essa.

Também não sei se posso setar mais de um CellEditor para a coluna. Acho que não né…, não sei…

O exemplo abaixo é bem parecido com o que eu quero, pois ele valida se foi digitado caracteres não numéricos e na mesma classe que eu possuo no meu sistema.
O problema é que ele valida o campo após perder o foco. No caso eu gostaria de bloquear os caracteres não númericos. Esse problema não impacta muito na continuação do meu projeto. Seria mais um padrão de beleza para facilitar ao usuário.

[code]TableColumn col = tabela.getColumnModel().getColumn(1);
col.setCellEditor(new MyTableCellEditor());

class MyTableCellEditor extends AbstractCellEditor
implements TableCellEditor{
JComponent component = new JTextField();

public boolean stopCellEditing(){
String s = (String)getCellEditorValue();
boolean valido = true;

for(int i = 0; i < s.length(); i++){   
  Character caractere = s.charAt(i);   
  if(!Character.isDigit(caractere)){   
    valido = false;   
    break;   
  }   
}       

if(!valido){   
  JOptionPane.showMessageDialog(null,   
     "Valor inválido");   
  return false;   
}   
return super.stopCellEditing();   

}

public Component getTableCellEditorComponent(
JTable table, Object value,
boolean isSelected, int rowIndex, int vColIndex){

if(isSelected){   
  //   
}   
   
((JTextField)component).setText((String)value);   
   
return component;   

}

public Object getCellEditorValue() {
return ((JTextField)component).getText();
}
}
[/code]

Boa noite Blst.

Entendi o que voce quer fazer, neste caso dá até para implementer um Evento KeyListener e capturar a tecla pressionada, sabe onde :?:

Dentro da sua Classe MyTableCellEditor, assim:

public class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor, KeyListener {

    private JTextField text;

    public Object getCellEditorValue() {
        return text;
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
        text = new JTextField();
        text.addKeyListener(this);
        text.setText((String)value);
        return text;
    }

    public void keyTyped(KeyEvent e) {
        if (e.getSource()==text){
            if (e.getKeyChar()<'0' || e.getKeyChar()>'9'){
                JOptionPane.showMessageDialog(null, "Valor inválido");
                e.setKeyChar(' ');
            }
        }
    }

    public void keyPressed(KeyEvent e) {
        // Evento não utilizado, porém precisa ser declarado
    }

    public void keyReleased(KeyEvent e) {
        // Evento não utilizado, porém precisa ser declarado
    }

}

Repare que voce não precisou nem utilizar o método stopCellEditing().

Outra coisa que percebi é que não precisava voce declarar um JTextField como Component e depois fazer o Casting, repare que o declarei com JTextField direto e ele o retorna como Component sem precisar fazer o Casting, isto é desperdício de recurso, isto porque o JTextField herda (extende) de Component e Component herda de Object