JTable[Resolvido]

8 respostas
vielmateus

Boa noite,

Estou fazendo um aplicativo para uso em minha empresa, tenho algumas dúvida, segue:

  1. Tenho um JTable, o mesmo permite editar as informações contidas em suas linhas, preciso que isso seja barrado, e que seja possível selecionar as linhas, o que já acontece hoje. Como posso alterar essa propriedade?

  2. Quando abro mais do que uma tela, e clica no famoso “X” para fecha, todo programa é fechado, como posso definir para que feche somente a tela em uso?

Desculpem se não fui claro, mas é meu primeiro post.

Obrigado pela ajuda.

8 Respostas

igor_jua
jTable.setEditable(false);
  1. Na classe que implementa seu JFrame chame o método
this.setDefaultCloseOperation(this.HIDE)
Marky.Vasconcelos

Voce devia colocar no model da JTable retornar false no método isEditable(int row, int col).

E nos JFrames voce precisa colocar setDefaultCloseOperation como JFrame.HIDE ou JFrame.DISPOSE

vielmateus

O setDefaultCloseOperation ficou legal, 100%.

Já sobre o jTable não estou conseguindo fazer, vou colocar o método que popula a jTable:

private void populaTabela(ResultSet rs) {
        DefaultTableModel modelo = (DefaultTableModel) jTable1.getModel();
        try {
            while (rs.next()) {
                Vector registro = new Vector<String>();
                registro.add(rs.getInt("oco.i_cod_oco"));
                registro.add(rs.getString("cli.c_nom_cli"));
                int statOco = Integer.parseInt(rs.getString("oco.i_sta_oco"));
                switch (statOco) {
                    case 1:
                        registro.add("Aberto");
                        break;
                    case 2:
                        registro.add("Aberto / Desenvolvimento");
                        break;
                    case 3:
                        registro.add("Fechado");
                        break;
                    case 4:
                        registro.add("Cancelado");
                        break;
                }
                registro.add(rs.getString("oco.d_dat_cad"));
                modelo.addRow(registro);
            }
        } catch (SQLException ex) {
            Logger.getLogger(jConsultaCliente.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Devo inserir o código aqui, estive pesquisando e o pessoal fala em extender a classe AbstractTableModel, alguém pode me explicar melhor?

Marky.Vasconcelos

Foi bem o que voce leu mesmo, precisa extender AbstractTableModel.

Dai voce nao vai precisar desse Vector de Strings, e nem desse DefaultTableModel, voce vai trabalhar diretamente com o tipo de objeto que voce tem.

vielmateus

Isso mesmo Marky, consegui fazer algo do genero, e está resolvendo, de maneira simples.

Estou com dois problemas:

1) As colunas não estão assumindo o nome correto,
2) Alguns campos na tela precisam ser preenchidos conforme é clicado sobre as linhas da tabela.

Pode me ajudar?

Vou colocar o código que criei.

Classe AbstractTableModel
public final class jTable extends AbstractTableModel {

    private ArrayList linhas = null;
    String[] colunas = null;

    public jTable(ArrayList dados, String[] coluna) {
        setLinhas(dados);
        setColunas(coluna);
    }

    public String[] getColunas() {
        return colunas;
    }

    public ArrayList getLinhas() {
        return linhas;
    }

    public void setColunas(String[] strings) {
        colunas = strings;
    }

    public void setLinhas(ArrayList list) {
        linhas = list;
    }

    public int getRowCount() {
        return getLinhas().size();
    }

    public int getColumnCount() {
        return getColunas().length;
    }
  public Object getValueAt(int rowIndex, int columnIndex) {
        String[] linha = (String[]) getLinhas().get(rowIndex);
        return linha[columnIndex];
    }
}
Tela
private void populaTabela(ResultSet rs) {
        String[] colunas = new String[]{"Código", "Cliente", "Status", "Data Abertura", "Motivo Cancelamento", "Usuário"};
        ArrayList dados = new ArrayList();
        String status = null;
        try {
            while (rs.next()) {
                int statOco = rs.getInt("oco.i_sta_oco");
                switch (statOco) {
                    case 1:
                        status = ("Aberto");
                        break;
                    case 2:
                        status = ("Aberto / Desenvolvimento");
                        break;
                    case 3:
                        status = ("Fechado");
                        break;
                    case 4:
                        status = ("Cancelado");
                        break;
                }
                dados.add(new String[]{
                            rs.getString("oco.i_cod_oco"),
                            rs.getString("cli.c_nom_cli"),
                            (status),
                            rs.getString("oco.d_dat_cad"),
                            rs.getString("oco.c_mot_can"),
                            rs.getString("oco.i_cod_usu")});
            }

        } catch (SQLException ex) {
            Logger.getLogger(jConsultaCliente.class.getName()).log(Level.SEVERE, null, ex);
        }
        jTable modelo = new jTable(dados, colunas);
        jTable1.setModel(modelo);
    }
Nicolas_Fernandes

Tá quase lá, vielmateus!

Faça o seu TableModel tipado, ou seja, voltado para algum objeto específico.
Suponhamos que essa seja minha classe Aluno:

public class Aluno
{
   private int codigo;
   private String nome;
   private Turma turma;
}

public class Turma
{
   private int codigo;
   private String nome;
}

E esse meu AlunosTableModel (veja que todos os métodos são baseados no meu objeto Aluno):

public class AlunosTableModel extends AbstractTableModel
{
   // Defino as colunas que terei
   private static final int colunaNome = 0;
   private static final int colunaTurma = 0;

   // Lista de controle de dados
   private List<Aluno> alunos = new ArrayList<Aluno>();

   public AlunosTableModel(List<Aluno> alunos)
   {
      this.alunos = alunos;
   }

   @Override public int getRowCount() 
   {  
      return alunos.size();
   } 

   @Override public int getColumnCount()
   {
      return 2;
   } 

   @Override public Object getValueAt(int row, int col)
   {
      Aluno aluno = alunos.get(row);
      
      if ( col == colunaNome ) return aluno.getNome();
      if ( col == colunaTurma ) return aluno.getTurma().getNome();

      return "";
   }

   @Override public String getColumnName(int col)
   {
      if ( col == colunaNome ) return "Nome do Aluno";
      if ( col == colunaTurma ) return "Turma";

      return "";
   }

   @Override public Boolean isCellEditable(int row, int col)
   {
      return false;
   }


   // Posso criar métodos de ação, também:
   public void adicionarRegistro(Aluno aluno)
   {
      alunos.add(aluno);
      fireTableRowsInserted(alunos.size(), alunos.size());
   }
   public void alterarRegistro(int row, Aluno aluno)
   {
      alunos.get(row).setNome(aluno.getNome());
      alunos.get(row).setTurma(aluno.getTurma());
      fireTableRowsUpdated(row, row);
   }
   public void removerRegistro(int row)
   {
      alunos.remove(row);
      fireTableRowsDeleted(row, row);
   }

   // E por aí vai...
}

Para colocar na JTable:

AlunosTableModel model = new AlunosTableModel(/*Passa sua coleção de dados por parâmetro*/);
JTable table = new JTable(model);

Aluno aluno;

aluno = new Aluno(1, "João", new Turma(1, "Turma Noturno"));
model.adicionarRegistro(aluno);

aluno = new Aluno(2, "Maria", new Turma(1, "Turma Diurno"));
model.adicionarRegistro(aluno);

aluno = new Aluno(3, "Pedro", new Turma(1, "Turma Noturno"));
model.adicionarRegistro(aluno);

aluno = new Aluno(3, "Pedro Antônio", new Turma(1, "Turma Noturno"));
model.alterarRegistro(2, aluno);

model.removerRegistro(1);

Testa aí e nos dê um reply!
Abraço!

M

Além das dicas que o Nicolas Fernandes deu, leve em consideração o seguinte:

  1. Criar seu próprio TableModel serve justamente para que você evite trabalhar com Strings (afinal, Java é orientado a objetos, não a Strings). Veja o exemplo que o Nicolas postou e os links na minha assinatura para mais detalhes.

  2. Falta métodos para adicionar/remover objetos do seu modelo.

  3. Você sempre sabe os nomes das colunas. Isso quer dizer que são dados estáticos, não precisando ser passados via argumento no construtor.

vielmateus

Certinho, obrigado a todos pela ajuda,
fiz exatamente como Marky falou,

O nome da coluna não estava aparecendo por faltar o método:

public String getColumnName(int column) { return colunas[column]; }

Simples, mas necessário.

Criado 30 de agosto de 2010
Ultima resposta 9 de out. de 2010
Respostas 8
Participantes 5