Herança visual de JFrame

5 respostas
J

Estou trabalhando com Netbeans 7.1 e estou com duvidas em relação a herança da parte visual do formulário JFrame, pois quero a partir de um formulário padrão herdar não só os métodos mas também os componentes gráficos, vi alguns posts mais antigos sobre este assunto, porem não sei houve melhorias em relação a isso na versão 7.1 do Netbeans.

Obrigada.

5 Respostas

N

Oi, Jaqueline Rissato, tudo bem?

Veja bem. Espero que você esteja criando suas interfaces na mão. Fica mais simples de você enxergar heranças e polimorfismos de seus JFrames.
Você pode trabalhar da seguinte forma:

1. No seu JFrame pai, você cria um componente protegido ou privado (mas com um get pra ele);
2. Você cria toda a parte comum da visualização, adiciona no JFrame pai e, nos JFrames filhos, adiciona os componentes dentro daquele criado no item 1 (sugiro que este do item 1 seja um JPanel, para colocar todo o conteúdo diferente a ser mostrado);
3. No JFrame filho, você sobrescreve os métodos do JFrame pai e preenche o componente criado no item 1.

Veja só um exemplo simples do que quero dizer:
public abstract class FramePai extends JFrame {

    private JPanel panelContent;
    private JPanel panelActions;
    private JButton buttonConfirm, buttonCancel;

    public FramePai() {
    
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception exception) {
            JOptionPane.showMessageDialog(null, "Erro ao criar o L&F do sistema! " + exception.getMessage());
        }

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        setResizable(false);
  
        // Adiciono o panelActions para ser o "comum" entre os filhos.
        panelActions = new JPanel(new FlowLayout(FlowLayout.RIGHT));
       
        buttonConfirm = new JButton("Confirm");
        buttonConfirm.addActionListener(new ConfirmActionListener());
        panelActions.add(buttonConfirm);

        buttonCancel = new JButton("Cancel");
        buttonCancel.addActionListener(new CancelActionListener());
        panelActions.add(buttonCancel);

        // o panel de conteúdos vai no centro, ou onde você quiser.
        panelContent = new JPanel();
        add(panelContent, BorderLayout.CENTER);
    }
 
    public JPanel getPanelContent() {
        return panelContent;
    }

    // Ação do botão Confirm que será sobrescrita nos filhos.
    protected abstract void onConfirmClick(ActionEvent event);
    private class ConfirmActionListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            onConfirmClick(event);
        }
    }

    // Ação do botão Cancel que será sobrescrita nos filhos.
    protected abstract void onCancelClick(ActionEvent event);
    private class CancelActionListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            onCancelClick(event);
        }
    }
}

public class FrameFilhoUm extends FramePai {

    public FrameFilhoUm() {

        // dou um get no panel de conteúdo e adiciono os dados nele.
        getPanelContents().add(new JLabel("Frame filho um!"));
    }

    // Como a classe pai têm métodos que devem ser sobrescritos, aí vão eles:

    @Override public void onConfirmClick(ActionEvent event) {
        JOptionPane.showMessageDialog(null, "Botão confirm => frame filho um!");
    }

    @Override public void onCancelClick(ActionEvent event) {
        JOptionPane.showMessageDialog(null, "Botão cancel => frame filho um!");
    }
}

public class FrameFilhoDois extends FramePai {

    public FrameFilhoDois() {
        getPanelContents().add(new JLabel("Frame filho dois!"));
    }

    @Override public void onConfirmClick(ActionEvent event) {
        JOptionPane.showMessageDialog(null, "Botão confirm => frame filho dois!");
    }

    @Override public void onCancelClick(ActionEvent event) {
        JOptionPane.showMessageDialog(null, "Botão cancel => frame filho dois!");
    }
}

Consegue entender mais ou menos a ideia?
Fique com Deus! :D

J

Ola Nicolas Fernandes,

Tentei usar JPanel pra criar meu componente padrão, e assim adiciona-lo nos JFrames. No caso criei um grupo de botoes no JPanel que estará em quase todos os JFrames, por exemplo o botão incluir, o método é o mesmo em todos todos os JFrames o que muda é o caminho onde o botão vai incluir os dados, então não sei se é possível no JFrame sobrescrever o método do JPanel padrão e alterar estes detalhes. Desculpe mas não sei se foi o que você quis dizer no exemplo acima. :slight_smile:

N

Jaqueline Rissato:
Ola Nicolas Fernandes,

Tentei usar JPanel pra criar meu componente padrão, e assim adiciona-lo nos JFrames. No caso criei um grupo de botoes no JPanel que estará em quase todos os JFrames, por exemplo o botão incluir, o método é o mesmo em todos todos os JFrames o que muda é o caminho onde o botão vai incluir os dados, então não sei se é possível no JFrame sobrescrever o método do JPanel padrão e alterar estes detalhes. Desculpe mas não sei se foi o que você quis dizer no exemplo acima. :)

Sim, foi exatamente o que eu quis dizer!
Veja bem. Você deve:

  1. Crie um método abstrato e protegido, o qual receberá por parâmetro um ActionEvent e será responsável por definir o comportamento do seu botão Incluir;
  2. Crie uma classe privada que implementará a interface ActionListener;
  3. O método actionPerformed deve chamar o seu método abstrato. O método abstrato vai ser implementado de um modo diferente em cada frame filho; logo, ao chamar o frame específico, o botão se comportará do jeito específico que você definiu naquele Frame!

No meu código no post acima tem isso exemplificado.
Fique com Deus! :smiley:

J

Na verdade estou usando o JFrame e o Jpanel pronto, não estou criando na mão, mas vou testar desta forma. Obrigado pela dica Nicolas!

N

Você já sabe como fazer isso na mão, ou aprendeu a criar formulários diretamente pelo Netbeans?
Se não sabe ainda, sugestão: aprenda a criá-los por si só, como no código que fiz acima. Assim, você entenderá a estrutura que se passa por trás de gerenciadores de layout. Além do mais, criando na mão, você pode “despoluir”, eventualmente, o código gerado pelo Netbeans para os formulários, por exemplo. Primeiro vale a pena conhecer o “caminho das pedras”, o “por dentro”, para então usar uma tecnologia pronta. Fica a dica!

Outra coisa: para trabalhar com o polimorfismo, insira seus métodos abstratos dentro da classe gerada pelo Netbeans e, no evento ActionPerformed do botão, você chama esse método, e o resto é o que postei na minha última resposta.

:slight_smile:

Criado 22 de outubro de 2012
Ultima resposta 23 de out. de 2012
Respostas 5
Participantes 2