Herança visual de JFrame

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.

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:[code]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!");
}

}
[/code]

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

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:

[quote=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. :)[/quote]

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:

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!

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: