Java Jtable e Jcombobox

Tenho um Jdialog que se chama FrmOs - Ordem de serviço, onde eu tenho um Jcombobox de Serviço que é do tipo Serviço e eu também tenho um botão de pesquisa, para pesquisar um serviço.

Abaixo segue a tela de frmOs - Ordem de serviço. quando eu clicar na lupa, abre uma janela de pesquisa de serviço.

Esta é a Janela de consulta serviço, quando eu clicar 2 vezes em uma linha(serviço) ela retorna para a Janela de frmOs - ordem de serviço. No exemplo eu cliquei em LAVAGEM SIMPLES

Minha dúvida é quando eu clicar 2 vezes na Jtable de Serviços eu quero retornar para Janela FrmOs o serviço selecionado em meu Jcombobox, abaixo é a tela final depois que cliquei 2 vezes, no campo valor e campo código eu consegui setar os valores do serviço selecionado da tabela. só que no meu Jcombobox não ficou certo.

Este código chama a tela de consulta e depois seta os valores em seus campos.

private void cbbPesquisaServicoActionPerformed(java.awt.event.ActionEvent evt)
{
frmConsultaServico pesquisa = new frmConsultaServico(null, true);
pesquisa.show();

    if (pesquisa.cod > 0)
    {
        Servico s = ctrser.getServicoCodigo(pesquisa.cod);

        cbbServico.setSelectedItem(s);
        txtCodigoServico.setText(String.valueOf(s.getCodigo()));
        txtCodigoServico.setHorizontalAlignment(JTextField.CENTER);
        txtValor.setValue(s.getValor());
        txtValor.setHorizontalAlignment(JTextField.CENTER);
    }
}                                                  

Código quando clica 2 vezes na Jtable

private void tbServicosMouseClicked(java.awt.event.MouseEvent evt)                                        
{                                            
    if (evt.getClickCount() == 2)
    {
        int linha = tbServicos.getSelectedRow(); // linha selecionada
        cod = (Integer) tbServicos.getValueAt(linha, 0); //pega o codigo do serviço na linha selecionada
       // servico = ctrser.getServicoCodigo(cod);
        dispose();
    }
}

Olá,
Você vai precisar setar direto o serviço selecionado no combo ANTES de fechar o form de pesquisa.
Para ter acesso a isso, ao abrir o form de pesquisa, passe por parâmetro o form da OS. Algumas modificações serão necessárias, mas a lógica é essa.
Exemplo:
frmConsultaServico pesquisa = new frmConsultaServico(null, true, this);
Onde o this representa a instância do form de OS. Mas para isto funcionar, modifique o construtor do form de pesquisa para aceitar como parâmetro um frmConsultaServico.

1 curtida

Outra coisa,
aparentemente vc não implementou seu TableModel e está usando DefaultTableModel. Não faça isso, implemente seu tablemodel, é muito melhor, sem contar que pelo menos usa Orientação a Objetos.

2 curtidas

Cara muito obrigado por me passar mais esta informação, vai ser de grande valia.

certo, mas o que eu colocaria no construtor do frmConsultaServico, ele é um JDialog

public frmConsultaServico(java.awt.Frame parent, boolean modal)
{
   super(parent, modal);
   initComponents();
}
1 curtida
private FrmOs frmOs;

public frmConsultaServico(java.awt.Frame parent, boolean modal, FrmOs frmOs)
{
       super(parent, modal);
       initComponents();
       this.frmOs = frmOs;
}

Ai no frmOs cria um método publico para setar o serviço no combo.

Exemplo.:

public void setServico(Servico s) {
 //seta no combo
}

depois lá no evento de 2 clicks é só chamar:

frmOs.setServico(s);

mas vai precisar ter o objeto Servico, por isso é importante implementar um ObjecttableModel ao invés de usar o Default, fica bem mais fácil.

2 curtidas

Certo, antes de tudo estou implementando a tabela. Fiz a classe, mas fiz uma que dê pra usar em todas, mas com o mesmo sentido que vce me falou. Só que não consigo preencher ela olhe meu código.

meu ArrayList recebe o que o usuário está procurando, este ctrser é uma controladora que manda para DAO consultar e retornar para ela. segue abaixo a DAO

public ArrayList<Servico> recuperaDadosTabela(String sCriterio)
{
    ArrayList<Servico> lista = new ArrayList();
    Servico s;
    String query = "select ser_cod, ser_descricao, ser_valor, ser_datacadastro from servico where ser_descricao like '%" + sCriterio + "%' order by ser_descricao";
    ResultSet rs = Banco.getCon().consultar(query);

    try
    {
        while (rs.next())
        {
            s = new Servico();
            s.setCodigo(rs.getInt("ser_cod"));
            s.setDescricao(rs.getString("ser_descricao"));
            s.setValor(rs.getBigDecimal("ser_valor"));
            s.setDataCadastro(rs.getDate("ser_datacadastro"));
            lista.add(s);
        }
    } catch (Exception e)
    {
        System.out.println(e.getMessage());
    }

    return lista;
}

e a controladora

public ArrayList<Servico> recuperaDadosTabela(String sCriterio)
{
    return daoServico.recuperaDadosTabela(sCriterio);
}


public void preencherTabela2()
{
   ArrayList dados = new ArrayList();
    
    String [] colunas = new String[]{"CÓDIGO","SERVIÇO","VALOR","DATA CADASTRO"};
    
    dados = ctrser.recuperaDadosTabela(txtDescricao.getText().toUpperCase());

    for (int i = 0; i < dados.size(); i++)
    {
       dados.add(new Object[]
        {
           dados
        });
    }
    
    ModeloTabela modelo = new ModeloTabela(dados,colunas);
    tbServico.setModel(modelo);
    tbServico.getColumnModel().getColumn(0).setPreferredWidth(50);

}
1 curtida

Se realmente estão chegando dados ao modelo, o problema é a ModeloTabela. Poste o código dela.

1 curtida

@Leandro17 você poderia passar uma dica de como fez o layout das suas telas, ficaram muito boas tbm utilizo muito java swing .
Obrigado.

1 curtida
public class ModeloTabela extends AbstractTableModel
{

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

    public ModeloTabela(ArrayList lin, String[] col)
    {
        setLinhas(lin);
        setColunas(col);
    }

    public ArrayList getLinhas()
    {
        return linhas;
    }

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

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

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

    @Override
    public int getColumnCount()
    {
        return colunas.length;
    }

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

    @Override
    public String getColumnName(int numCol)
    {
        return colunas[numCol];
    }

    @Override
    public Object getValueAt(int numLin, int numCol)
    {
      Object[] linha = (Object[])getLinhas().get(numLin);
      return linha[numCol];
    }

}
1 curtida

Estou usando um dos temas do Synthetica, segue o link http://www.javasoft.de/synthetica/themes/%3Bjsessionid%3D5194ac1c4e3d3ebf515c7e322899

muito obrigado @Leandro17

1 curtida

Cara, este seu método preencherTabela2 está meio sem lógica (Assim como o tableModel, rsrrs)
Tente assim:

public void preencherTabela2()
{
    String [] colunas = new String[]{"CÓDIGO","SERVIÇO","VALOR","DATA CADASTRO"};
    
    dados = ctrser.recuperaDadosTabela(txtDescricao.getText().toUpperCase());
    
    ModeloTabela modelo = new ModeloTabela(dados,colunas);
    tbServico.setModel(modelo);
    tbServico.getColumnModel().getColumn(0).setPreferredWidth(50);
}

Não era bem esta a ideia de TableModel Orientado a Objetos, vc recriou o DefaultTableModel. Se quer ele genérico, precisa usar Generics.

1 curtida

Entendi, sim eu queria criar um que desse para reutilizar em outras Jtable, porque em meu ponto de vista, criando minha própria Table Model de Serviço, eu também teria que criar outra Table Model para Clientes, Fornecedores, Produtos e etc. Isso não acaba ficando grande? Porque por aquele exemplo que você me passou eu entendi, só não muito na hora de preencher a tabela. Mas para que eu consiga selecionar um Item da Jtable e retornar no Jcombobox se eu precisar usar o que você me passou vou ter que aderir. E muito obrigado por tirar todas essas minhas dúvidas. @Rodrigo_Void

Depende o caso, em projetos simples o mais rápido é implementar um para cada tipo, também mais fácil de usar.
É bom ter um genérico, mas precisa ser genérico de verdade, usando Generics, NÃO OBJECT. Parecido como usar um List, onde ao criar vc especifica o tipo. Dá trabalho fazer, mas uma vez pronto, pode sempre reutilizar. E como eu disse, precisa ver se vale a pena tamanho esforço para um projeto pequeno. Na verdade já tem bibliotecas prontas na net que implementam ObjectTableModel genérico, não precisa fazer. Não acho que vale a pena fazer um, pois vai cair em várias situações específicas de cada tipo que quiser usar, como formatação de número na célula, e ai o barco afunda, então use algum pronto que já te traz isso: