24 de agosto de 2010

Swing: Preenchendo um JComboBox

Nesse post iremos preencher um JComboBox com objetos, para isso vamos precisar de uma java.util.List.
Para exemplo vamos usar uma categoria. Então... precisamos de uma classe chamada Categoria.java

public class Categoria {

    private int codigo;
    private String nome;

    public int getCodigo() {
        return codigo;
    }

    public void setCodigo(int codigo) {
        this.codigo = codigo;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    @Override
    public String toString() {
        return this.nome;
    }

}
Perceba que o método toString() foi sobreescrito, isso é necessário para que ao mostrar os objetos no JComboBox, apareça o nome da categoria como referência no combo... para entender a importância disso, faça um teste: retire o método toString() e veja o resultado!

Continuando...
Crie um Formulário JFrame com o nome de ExemploCombo.java, e arraste para a tela, um JComboBox (cmbCategoria) e um JButton (btnEnviar) para testarmos.
A janela deverá ficar como a imagem abaixo:

No código-fonte crie um método carregaCombo(), com o seguinte código:
private void carregaCombo(){
        //assim como é feito numa JTable, temos o DefaultComboBoxModel que é o model do JComboBox
        DefaultComboBoxModel comboModel = (DefaultComboBoxModel) cmbCategoria.getModel();
        //removendo todos os elementos do combo
        comboModel.removeAllElements();
        //cria a lista: java.util.List
        List<Categoria> categorias = new ArrayList<Categoria>();
        //adicionando valores aleatorios a lista
        Categoria c1 = new Categoria();
        c1.setCodigo(1);
        c1.setNome("Compra");
        categorias.add(c1);

        Categoria c2 = new Categoria();
        c2.setCodigo(2);
        c2.setNome("Venda");
        categorias.add(c2);
        //percorrendo a lista para inserir os valores no combo
        for (int linha = 0; linha < categorias.size(); linha++)
        {
            //pegando a categoria da lista
            Categoria categoria = categorias.get(linha);
            //adicionando a categoria no combo
            comboModel.addElement(categoria);
        }
    }
Os comentários no código explicam o que acontece em cada linha.
Agora é necessário chamar este método no construtor da classe, logo depois de iniciar os componentes:
public ExemploCombo() {
        initComponents();
        carregaCombo();
    }

E para pegar o valor, vamos utilizar o evento do btnEnviar, para isso dê dois cliques no botão para abrir o evento:
private void btnEnviarActionPerformed(java.awt.event.ActionEvent evt) {                                         
        //pegando o objeto selecionado no combo
        Categoria categoria = (Categoria) cmbCategoria.getSelectedItem();
        //mostrando o nome da categoria em um dialogo
        JOptionPane.showMessageDialog(this, categoria.getNome());
    }

Para setar um objeto por padrão em um combo, segue o exemplo:
cmbCategoria.setSelectedItem(categoria);
Essa categoria que está sendo passada por parâmetro, seria uma categoria por exemplo pega de uma lista, ou de um outro objeto que possua uma categoria.

=)

18 de agosto de 2010

JavaSE: Converter java.util.Date para String e vice-versa

Converter String para java.util.Date
Para converter uma String em java.util.Date, é necessário utilizar a classe java.text.SimpleDateFormat, passado uma String por parâmetro que se refere ao formato em que se encontra a String que será convertida:
SimpleDateFormat formataData = new SimpleDateFormat("dd/MM/yyyy");
Date dataEntrada = null;
try { 
    dataEntrada = formataData.parse("21/09/2010");
} catch (ParseException ex) {
    ex.printStackTrace();
}

Converter java.util.Date para String
Quando se tem um Date e quer transformar em String é só utilizar o mesmo SimpleDateFormat. O 'new Date()' pega a data atual do sistema, a String passada por parâmetro para SimpleDateFormat é o formato em que se deseja que a String seja formatada:
Date dataHoje = new Date();
SimpleDateFormat formataData = new SimpleDateFormat("dd/MM/yyyy");
String data = formataData.format(dataHoje);

Por se tratar de uma formatação onde não há riscos de ocorrer erros, não é necessário colocar a formatação dentro de um bloco 'try catch' como a conversão anterior.

15 de agosto de 2010

JavaSE: CRUD em Swing

Neste post, iremos implementar parte do projeto do Hotel  da postagem: UML: Trabalhando com a diagramação . Este sistema será implementado em Java SE (para Desktop), com armazenamento em estruturas de dados (mais especificamente em java.util.List).
O sistema final terá a seguinte estrutura:
Obs: as classes do pacote model são as mesmas criadas na aula citada no link acima.
Mas, neste post será criado apenas o cadastro de Aposentos... então vamos lá!

Criando o projeto...
Neste projeto será utilizado o NetBeans, neste crie um novo projeto: Arquivo -  Novo Projeto - Java -  Aplicativo Java, e coloque o nome do projeto como: Hotel.

Criando o banco de dados...
Considerando que o pacote model já esteja implementado, vamos começar criando nossa classe que servirá de banco de dados, então dentro do pacote hotel, crie uma nova classe java chamada de BancoDados.java, com o seguinte codigo:
public class BancoDados {

    private static List<Aposento> aposentos = new ArrayList<Aposento>();
 
    /*
     * Aposentos
     */

    public static List<Aposento> getAposentos() {
        return aposentos;
    }

    public static void addAposento(Aposento aposento){
        aposentos.add(aposento);
    }

    public static void atualizaAposento(int linhaSelecionada, Aposento aposento){
        aposentos.set(linhaSelecionada, aposento);
    }

    public static void removeAposento(Aposento aposento){
        aposentos.remove(aposento);
    }
}
Perceba que nossos métodos são static, pois como instanciaremos apenas uma única vez nosso BancoDados, os mesmos precisarão ser acessados mas sem instanciar um novo BancoDados, isso será entendido melhor mais pra frente...

Tela inicial...
Ainda dentro do pacote hotel, crie um Formulário JFrame, chamado de Principal.java, este será nossa tela inicial do sistema. Por ser um JFrame o NetBeans dá a opção de criar a tela arrastando os componentes, então arraste um botão (JButton) para o formulário, este ficará com a seguinte aparência:

Chamando nossa tela principal...
Na classe Main.java que foi criada juntamente com o projeto, insira o seguinte codigo:
public class Main {

    public static void main(String[] args) {
       new BancoDados();

       JFrame principal = new Principal();
       principal.setVisible(true);
    }
}
perceba que nosso BancoDados está sendo instanciado, isso garante que ele seja inicializado junto com o sistema. E após ele, está sendo instanciado nosso formulário JFrame Principal.java, que é a tela inicial do sistema.
Para visualizar a aplicação, basta apertar a tecla F6 (padrão do NetBeans para executar a aplicação).

Criando a tela principal de aposentos
Agora crie um pacote chamado aposento, dentro do pacote hotel, naquele crie um novo formulário JFrame chamado Aposentos.java, arraste para a tela três botões (JButton) e uma tabela (JTable). Altere o nome das variáveis dos botões para: btnNovo, btnAlterar e btnRemover.

Para alterar os campos da tabela, clique nela com o botão direito e clique em conteúdo da tabela e vá na aba colunas, e edite as mesmas. Depois, clique novamente na tabela e vá em propriedades - aba código, e altere os modificadores de variáveis, o mesmo deve ficar como private static. Isso precisa ser feito para criamos um método estático de atualização da tabela, pois é o mesmo caso do BancoDados, mais pra frente precisaremos chamar este método sem instanciar um novo objeto Aposentos(). Então, no código fonte de Aposentos.java, insira o seguinte método(deve ficar dentro da classe):
public static void atualizaTabela(){
        DefaultTableModel tTabela = (DefaultTableModel) jTable1.getModel();
        tTabela.setNumRows(0);

        List<Aposento> aposentos = BancoDados.getAposentos();

        for (int linha = 0; linha < aposentos.size(); linha++)
        {
            Aposento aposento = aposentos.get(linha);

            tTabela.addRow(new Object[]{1});

            jTable1.setValueAt(aposento.getCodigo(), linha, 0);
            jTable1.setValueAt(aposento.getNumero(), linha, 1);
            jTable1.setValueAt(aposento.getDescricao(), linha, 2);
            jTable1.setValueAt(aposento.getValor(), linha, 3);
        }

    }
jTable1 é a minha tabela, caso esteja dando erro, verifique o nome da sua tabela.
Para que nossa tabela inicie atualizada, vamos chamar o método atualizaTabela() no construtor da classe Aposentos.java, ficando como o código abaixo:
public Aposentos() {
        initComponents();
        atualizaTabela();
    }

Agora iremos chamara tela de aposentos ao clicar no botão "Aposentos" na tela do frame Principal.java: então, em Principal.java de um duplo clique no botão "Aposentos" para que ele vá para o método do clique, onde será inserido o código para instanciar nosso frame Aposentos.java:
private void btnAposentosActionPerformed(java.awt.event.ActionEvent evt) {                                             
        JFrame aposentos = new Aposentos();
        aposentos.setVisible(true);
}    
No meu caso, eu alterei o nome da variável do meu botão para btnAposentos, por isso o nome do método inicia dessa forma.(isso vai ser de acordo com o nome dado ao botão aposentos)
Até este momento nossa aplicação já está abrindo a janela de aposentos ao clicar no botão "Aposentos" da tela inicial.

Tela de inserir aposento...
Dentro do pacote hotel.aposento crie um novo formulário JFrame com o nome de InserirAposento.java, crie a seguinte estrutura: quatro rótulos(JLabel), quatro campos de texto(JTextField) e dois botões (JButton)

Renomeie os nomes das variáveis dos campos de texto para: txtCodigo, txtNumero, txtDescricao, txtValor. E os botões para: btnOk, e btnCancelar.
Dê dois cliques no botão "Ok" para que ele vá para o método do clique do botão, e insira este codigo:
private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {                                         
        int iCodigo = Integer.parseInt(txtCodigo.getText());
        int iNumero = Integer.parseInt(txtNumero.getText());
        String sDescricao = txtDescricao.getText();
        double dValor = Double.parseDouble(txtValor.getText());
        Aposento aposento = new Aposento();
        aposento.setCodigo(iCodigo);
        aposento.setNumero(iNumero);
        aposento.setDescricao(sDescricao);
        aposento.setValor(dValor);

        BancoDados.addAposento(aposento);
        Aposentos.atualizaTabela();
        this.dispose();
    } 

Este método pega os valores dos campos, seta no objeto Aposento, e insere no nosso BancoDados, veja que não foi instanciado nenhum BancoDados aqui, lembre que se instancia apenas no Main.java. Depois que ele inserir, ele atualizará a tabela de aposentos pelo codigo Aposentos.atualizaTabela() que é o mesmo caso do BancoDados, e depois disto ele fecha a janela com o código this.dispose().
Agora dê um duplo clique no botão de cancelar:
private void btnCancelarActionPerformed(java.awt.event.ActionEvent evt) {                                         
    this.dispose();
}
Observe que o botão de cancelar, apenas fechará nossa janela.
Agora, iremos no Aposentos.java para chamar o InserirAposento. Então, vá em Aposentos.java e dê um duplo clique no botão "Novo":
private void btnNovoActionPerformed(java.awt.event.ActionEvent evt) {                                         
    JFrame janela = new InserirAposento();
    janela.setVisible(true);
}

Assim, nossa aplicação já está inserindo e listando os aposentos!

Alterando um aposento...
Para facilitar nossa implementação, ao invés de criar um novo JFrame para alterar o aposento, vamos copiar o InserirAposento.java e colar no mesmo pacote em que este se encontra, renomeando ele para AlterarAposento.java (ele vai pedir pra refatorar, então refatore!)
Vá para o código fonte do AlterarAposento.java e lá nas declarações dos atributos, declare os seguintes:
private Aposento aposento;
private int linhaSelecionada;
Logo abaixo do construtor do AlterarAposento.java, crie um novo construtor, passando um int por paramêtro, este int será a linha selecionada da tabela de Aposentos, que corresponde ao índice do aposento que foi selecionado na lista.
public AlterarAposento(int linhaSelecionada){
    initComponents();

    this.linhaSelecionada = linhaSelecionada;
    aposento = BancoDados.getAposentos().get(linhaSelecionada);
    codigo.setText(String.valueOf(aposento.getCodigo()));
    numero.setText(String.valueOf(aposento.getNumero()));
    descricao.setText(aposento.getDescricao());
    valor.setText(String.valueOf(aposento.getValor()));
}
Veja que estou setando a linhaSelecionada recebida por parâmetro na linhaSelecionada declarada na classe, pois esta será utilizada para setar o índice do objeto que será alterado na lista. A próxima linha: busca na lista do BancoDados o objeto Aposento daquela determinada linha. E quanto ao restante do código, estes setam os valores nos campos, para que ao abrir a janela, os campos estejam com os valores.
Agora dê um duplo clique no botão de Ok de AlterarAposento, perceba que este já está implementado pois foi copiado do inserir, então substitua o código pelo código a seguir:
private void btnOkActionPerformed(java.awt.event.ActionEvent evt) {                                         
    int iCodigo = Integer.parseInt(codigo.getText());
    int iNumero = Integer.parseInt(numero.getText());
    String sDescricao = descricao.getText();
    double dValor = Double.parseDouble(valor.getText());
    aposento.setCodigo(iCodigo);
    aposento.setNumero(iNumero);
    aposento.setDescricao(sDescricao);
    aposento.setValor(dValor);

    BancoDados.atualizaAposento(linhaSelecionada, aposento);
    Aposentos.atualizaTabela();
    this.dispose();
}
Deixe a implementação do botão "Cancelar" como ele está.
Vá para o JFrame Aposentos.java e dê um duplo clique no botão "Alterar", implemente o mesmo da seguinte forma:
private void btnAlterarActionPerformed(java.awt.event.ActionEvent evt) {                                         
    int linhaSelecionada = jTable1.getSelectedRow();

    if (linhaSelecionada >= 0){
        JFrame janelaAlterar = new AlterarAposento(linhaSelecionada);
        janelaAlterar.setVisible(true);
    }
    else{
        JOptionPane.showMessageDialog(this, "É necessário selecionar um aposento", "Aposento", JOptionPane.INFORMATION_MESSAGE);
    }        
}     
Analisando o código: nosso int linhaSelecionada está recebendo o valor da linha selecionada da tabela. Aí esta linha é verificada, para não ocorrer de abrir a janela de alterar aposento sem ter uma linha selecionada na tabela, por isso do if e else, caso a linhaSelecionada seja maior ou igual a 0, significa que tem uma linha selecionada na tabela, então será aberto a janela de AlterarAposento passando por parâmetro o valor desta linha, senão, abre uma janela dizendo que é necessário selecionar um aposento para alterar!

Removendo um aposento...
Para o remover aposento não será necessário um novo JFrame, iremos criar um JOptionPane. Então dê um duplo clique no botão "Remover" e insira o seguinte código:
private void btnRemoverActionPerformed(java.awt.event.ActionEvent evt) {                                         
    int linhaSelecionada = jTable1.getSelectedRow();

    if (linhaSelecionada >= 0){
        int resposta = JOptionPane.showConfirmDialog(this, "Deseja excluir o aposento?");
        if (resposta == JOptionPane.YES_OPTION){
            Aposento aposento = BancoDados.getAposentos().get(linhaSelecionada);
            BancoDados.removeAposento(aposento);

            atualizaTabela();
        }
    }
    else{
        JOptionPane.showMessageDialog(this, "É necessário selecionar um aposento", "Aposento", JOptionPane.INFORMATION_MESSAGE);
    }
}
Analisando  o código: Veja que parte do código é bem parecida com o evento do botão "Alterar", mas ao invés de chamar um novo JFrame, é criada uma janela de diálogo, que recebe um valor inteiro que em seguida é verificado, caso tenha clicado em Yes, o código para a remoção do aposento é executado!
E assim termina nosso cadastro de aposento =)