Herança de componetes [RESOLVIDO]

12 respostas
gimenezbr

Salve salve Galera.

Estou começando no mundo java e ja me deparei com uma dúvida.
Estou tentando reaproveitar componentes, exemplo:
Tenho um botão FECHAR na minha aplicação onde vou usar ele em vários lugares, então eu crio ele uma vez e estendo pra onde for usar, até ai tudo bem, depois de muito procurar vi que posso cria um projeto novo, criar esse botão, e depois clicando com o botão direto do mouse na classe dele, posso ir la e adicionar a Paleta de componentes.
Com isso, posso usar ele varios lugares, e se precisa alterar cor, ou alguma outra coisa, eu faço no pai, e ai aplica-se automaticamente a todos os filhos.

Isso eu ja consegui, mas quando faço isso, o botão herdado não tem o evento Action(ActionPerformed), que acho que equivale ao OnClick do Delphi.
Então eu não consigo escreve nada para quando ele receber um click.

Alguém poderia me ajudar e me dizer oque estou fazendo errado???

vlw

12 Respostas

gimenezbr

Se eu estiver no caminho errado, alguém poderia me dize também como proceder nesse sentido?

Quero usar componentes customizados, pois se um dia precisa muda uma coisa, não preciso mexe na aplicação toda.

marcoslogan

Cara, eu nunca fiz isso não. Mas vou adorar te ajudar a resolver esse problema. Você pode colocar o seu código-fonte aqui no guj, para eu analisá-lo?

fesaab

Eu entendi o teu problema, mas ta dificil te falar alguma coisa sem ver o codigo em…
Posta ele ai e agente analisa…

Abraço

gimenezbr

Bom, sobre o código é complicado, pq até agora eu fiz tudo automático, estou testando só as possibilidades, mas vamos la. Vou descrever como eu fiz aqui e ai vc tenta replicar ai, é bem simples o teste.

A versão do meu NETBEANS é:

Versão do produto: NetBeans IDE 6.8 (Build 200912041610)
Java: 1.6.0_19; Java HotSpot™ Client VM 16.2-b04
Sistema: Windows XP versão 5.1 executando em x86; Cp1252; pt_BR (nb)

Ai pra testa vc faz assim, Arquivo>Novo Projeto>Java>Aplicativo de area de trabalho Java
Ele monta um esqueleto pra vc de uma aplicação desktop, so para testarmos ta ótimo.
Dentro desse projeto mesmo, la na paleta projetos vc vai em Novo>Outro>Objetos JavaBeans>Personalizador, que foi oq apreendi faze para criar um componente personalizado. Depois de feito isso, ele abre tipo um JPanel, onde vc adiciona um componente qualquer e mudar cor fonte e etc.
Feito isso o componente ta pronto, ai vc vai la no item dele na paleta de projetos, clica com o botão direito do mouse e vai em Ferramentas>Adicionar a Paleta e escolhe um dos grupos de componentes para vincular ele, feito isso esse ja esta pronto para usar, ai vc pode ir la na paleta e adicionar ele ao seu projeto.

Até ai maravilha, mas quando faço isso, não fuciona o evento mencionado acima, a impressão que da é que os eventos são de um JPanel e não de um JButton.

Nó codigo, oq vejo é q:

Um botão normal fica assim la no final do código:

// Variables declaration - do not modify
private javax.swing.JButton jButton1;

e o herdado fica assim:

private desktopapplication2.x23 x231;

A Imagem abaixo mostra os eventos desse botão herdado, alguém poderia me dar uma luz?

gimenezbr

Fiz um exemplinho rápido aqui para pegar o código.

tenho dois arquivos, o frmPrincipal.java:

package my.ProjetoSoma;

public class frmPrincipal extends javax.swing.JFrame {

/** Creates new form frmPrincipal */
public frmPrincipal() {
    initComponents();
}


@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

    jbTeste1 = new javax.swing.JButton();
    jbFecharPadrao1 = new my.ProjetoSoma.jbFecharPadrao();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jbTeste1.setText("Teste1");
    jbTeste1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jbTeste1ActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jbTeste1)
            .addGap(61, 61, 61)
            .addComponent(jbFecharPadrao1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(161, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jbFecharPadrao1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jbTeste1))
            .addContainerGap(266, Short.MAX_VALUE))
    );

    pack();
}// </editor-fold>

private void jbTeste1ActionPerformed(java.awt.event.ActionEvent evt) {
    System.exit(0);
}


public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new frmPrincipal().setVisible(true);
        }
    });
}

// Variables declaration - do not modify
private my.ProjetoSoma.jbFecharPadrao jbFecharPadrao1;
private javax.swing.JButton jbTeste1;
// End of variables declaration

}

e o jbFecharPadrao.java que é esse que adiciono na Paleta para depois usar no código acima:

package my.ProjetoSoma;

public class jbFecharPadrao extends javax.swing.JPanel implements java.beans.Customizer {

private Object bean;

/** Creates new customizer jbFecharPadrao */
public jbFecharPadrao() {
    initComponents();
}

public void setObject(Object bean) {
    this.bean = bean;
}


// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

    jButton1 = new javax.swing.JButton();

    setLayout(new java.awt.BorderLayout());

    jButton1.setForeground(new java.awt.Color(255, 51, 0));
    jButton1.setText("Fechar Padrão");
    jButton1.setToolTipText("Sai da janela");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });
    add(jButton1, java.awt.BorderLayout.CENTER);
}// </editor-fold>

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    System.exit(0);
}


// Variables declaration - do not modify
private javax.swing.JButton jButton1;
// End of variables declaration

}

Nesse exemplo até fiz a parte de fechar o componente Pai, funciona certinho, mas não queria isso, o componente herdado eu queria a prior, so formata parte visual e tal, e depois onde herar ele codificar, mas não consigo, ele não tem os eventos.

*Obs, desculpa não colocar como código ai, não sei entre qual TAG tenho que por pra ficar formatadinho.

fesaab

Cara, eu fiz um negócio aki e funcionou…

O que eu entendi por esse Personalizador ai, eh que ele é um JPanel. Se vc olhar o código do teu Personalizador, vai ver que ele extende JPanel.
O que eu fiz foi o seguinte (e funcionou):

Criei uma nova classe “meubotao.java” e fiz essa classe extender JButton e implementar java.beans.Customizer (só pra deixar igual a estrutura do Personalizador).
Segue o código da classe:

public class meubotao extends javax.swing.JButton implements java.beans.Customizer {

    private Object bean;

    /** Creates new customizer NewCustomizer */
    public meubotao() {
        initComponents();
    }

    public void setObject(Object bean) {
        this.bean = bean;
    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        this.setText("meu botao");

        this.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                cliqueDoBotao();
            }
        });
    }// </editor-fold>

    private void cliqueDoBotao() {
        JOptionPane.showMessageDialog(null, "Clicou no botão!");
    }
}

Todo o código de personalização eu coloquei dentro do método initComponents(). No caso, vai ter o texto “meubotao” e quando clicar vai aparecer uma mensagem.

Depois disso COMPILE a classe, caso contrário não vai funcionar.\

Uma vez compilada, eu adicionei a classe à paleta como vc fez anteriormente: Ferramentas>Adicionar a Paleta

Agora sim, vc tem o teu componente reaproveitável! :smiley:

gimenezbr

Era isso mesmo, o problema é que ele estava estendendo da JPanel mesmo, achei que ele colocaria sozinho quando eu seleciona-se o componente.

Mas deu certo, era isso mesmo, muito obrigado.

So pra finaliza, isso que estou fazendo é o jeito correto para oq quero mesmo? Ou teria algo melhor pra se fazer?

No exemplo que fiz, ta tudo dentro de um mesmo projeto, mas a intenção é fazer todas a minhas classes e componentes em um projeto separado e depois importar para todo a aplicação que eu necessitar em forma de biblioteca JAR, ja fiz um teste e funciono. Com isso eu asseguro que seu eu precisa muda algo em alguma classe ou componente essa mudança vai se refleti para todas as aplicações que usam tal classe ou componente.

*So pra ajudar o iniciante aqui com futuras dúvidas, qual a TAG que uso quando for postar código aqui no forúm pra ele sai formatado como vc fez ai?

gimenezbr

Amigo, se puder me tira mais uma dúvida.

Quando eu crio um novo Personalizador para cria o meu botão, ele vem como estendido do JPanel, e visualmente parece ter um JPanel, ai arrasto um JButton pra ele, troco la no código de extends javax.swing.JPanel para extends javax.swing.JButton e salvo, depois adiciono a Paleta e pronto, so que quando adiciono em um projeto, ele parece ter dois botoes, ou um panel e um botão, fica estranho, que sera que to fazendo de errado?

gimenezbr

Cara, agora que entendi oq vc fez, vc não uso pelo Personalizador, fez na mão mesmo, mas é que personalizador fica mais fácil, pq eu vejo o botão e posso mexe em todas suas propriedades pela paleta de Propriedades.

Sera que so da pra fazer na mão mesmo?

fesaab

O que vc está fazendo é:

Criando sua própria classe que HERDA as propriedades de um JButton, ou seja, vc está criando seu próprio JButton.
Reaproveitando seu componente para utilizar em outros formulários.

Do jeito que vc está fazendo, seu componente vai estar disponível apenas enquanto o NetBeans encontrar teu projeto, pois o componente que vc adicionou na paleta é uma referência a essa classe no teu projeto.

Tem como vc adicionar definitivamente ele à paleta através do .jar da tua aplicação. Eu fiz um post no meu blog ensinando a adicionar um outro componente à paleta, mas o procedimento é o mesmo para qualquer componente. Vc pode dar uma olhada lá se quiser saber como fazer isso: http://www.javasimples.com.br/mundo-java/adicionando-jcalendar-e-jdatechooser-paleta-do-netbeans/

Algumas dicas gerais sobre o forum:

Para deixar o código bonito coloque ele entre as tags [ code] e [ /code] (sem os espaços).
Uma vez que teu problema foi resolvido, edite o título do tópico e coloque a tag [RESOLVIDO] no fim do título.

Abraços

fesaab

entao, eu nao sei se tem como fazer isso através do editor visual…
justamente pelo fato do Netbeans já criar uma herança de JPanel, o editor visual entende como se fosse um JPanel, mesmo que vc mude a herança…

Não sei mesmo se tem como fazer isso…
Mas não é muita desvantagem fazer na mão não… vc aprende os métodos dos componentes, podem ser úteis mais pra frente… ^^

boa sorte, e se achar como faz do jeito que vc quer, posta ai a solução… =]

gimenezbr

Opa, valew pela dica, sobre o .Jar é justamente oque fiz, e deu certinho, ele fica livre do projeto e posso usar em qualquer outro.

Sobre eu não estar conseguindo, deu certo viu, é que eu estava mudando de JPANEL para JBUTTON e ja estava testando na hora e ficava estranho, ai fechei e abri o NETBEANS novamente e ele volto certinho, so o botão mesmo.

Então é isso mesmo, funciona certinho.

Vlw pela ajuda.

Vou fechar o tópico.

*Se alguém precisa faze a mesma coisa e não consegui é so avisa, que comigo deu certinho.
Abraços

Criado 7 de abril de 2010
Ultima resposta 8 de abr. de 2010
Respostas 12
Participantes 3