Problema ao transferir dados entre JFrames

6 respostas
valmirknasel

Olá pessoal…

Meu problema é o seguinte:

tenho um JFrame que recebe os dados para cadastrar um filme, cujo código é:

package inventoryprogrampart5;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 *
 * @author Valmir Junior
 */
public class FrameCadastrateMovie extends JFrame {

    private static Movie movie;
    private static JPanel lbPanel;
    private static JPanel textFieldPanel;
    private static JPanel btnPanel;
    //create new JLabels.
    private JLabel lbMovieNumber = new JLabel("Movie Number:");
    private JLabel lbMovieName = new JLabel("Movie Name:");
    private JLabel lbMovieTitle = new JLabel("Movie Title:");
    private JLabel lbMovieQuantity = new JLabel("Movie Quantity:");
    private JLabel lbMovieUnitPrice = new JLabel("Unit Price:");
    private JLabel lbMovieMinimumStock = new JLabel("Minimum Stock:");
    //create the text fields.
    private JTextField jtfMovieNumber = new JTextField("", 30);
    private JTextField jtfMovieName = new JTextField("", 30);
    private JTextField jtfMovieTitle = new JTextField("", 30);
    private JTextField jtfMovieQuantity = new JTextField("", 30);
    private JTextField jtfMovieUnitPrice = new JTextField("", 30);
    private JTextField jtfMovieMinimumStock = new JTextField("", 30);
    //create the buttons.
    private JButton btnOk = new JButton("Add Movie");
    private JButton btnCancel = new JButton("Cancel");

    public FrameCadastrateMovie() {
        super();
        this.toInitialState();
    }

    public Movie getMovie() {
        return movie;
    }

    private void toInitialState() {
        //----------------------Sets the frame attributes-----------------------
        // set the size of the window - 400 is width, 300 is height
        this.setSize(300, 300);
        // set the title of the window
        this.setTitle("Movie");
        // center the form
        this.setLocationRelativeTo(null);
        //set the default close operation for this frame
        this.setDefaultCloseOperation(HIDE_ON_CLOSE);
        //store the frame components
        lbPanel = this.createLabelPanel();
        textFieldPanel = this.createFieldPanel();
        btnPanel = this.createButtonPanel();
        //add the frame components
        add(lbPanel, BorderLayout.WEST);
        add(textFieldPanel, BorderLayout.CENTER);
        add(btnPanel, BorderLayout.SOUTH);
    }

    private JPanel createLabelPanel() {

        //create a new JPanel to add the labels.
        JPanel labelPanel = new JPanel(new GridLayout(6, 1));
        //add the labels.
        labelPanel.add(lbMovieNumber);
        labelPanel.add(lbMovieName);
        labelPanel.add(lbMovieTitle);
        labelPanel.add(lbMovieQuantity);
        labelPanel.add(lbMovieUnitPrice);
        labelPanel.add(lbMovieMinimumStock);
        return labelPanel;
    }

    private JPanel createFieldPanel() {

        //create a new JPanel to add the Text Fields.
        JPanel txtFieldPanel = new JPanel(new GridLayout(6, 1));
        //add the text fileds to the textFieldPanel.
        txtFieldPanel.add(jtfMovieNumber);
        txtFieldPanel.add(jtfMovieName);
        txtFieldPanel.add(jtfMovieTitle);
        txtFieldPanel.add(jtfMovieQuantity);
        txtFieldPanel.add(jtfMovieUnitPrice);
        txtFieldPanel.add(jtfMovieMinimumStock);
        return txtFieldPanel;
    }

    private JPanel createButtonPanel() {
        //create an action listener to the buttons.
        class BtnListener implements ActionListener {

            public void actionPerformed(ActionEvent e) {
                if (e.getActionCommand().equals("Add")) {
                    try {
                        movie = new Movie();
                        movie.setItemNumber(Integer.parseInt(jtfMovieNumber.getText()));
                        movie.setItemName(jtfMovieName.getText());
                        movie.setTitle(jtfMovieTitle.getText());
                        movie.setQuantity(Integer.parseInt(jtfMovieQuantity.getText()));
                        movie.setUnitPrice(Double.parseDouble(jtfMovieUnitPrice.getText()));
                        movie.setLowStock(Integer.parseInt(jtfMovieMinimumStock.getText()));
//                        clearFields();
                        JOptionPane.showMessageDialog(null, "Movie Added");
                    } catch (NumberFormatException ex) {
                        JOptionPane.showMessageDialog(null, "Incorrect Values");
                    }
                } else if (e.getActionCommand().equals("Cancel")) {
                    dispose();
                }
            }
        }

        BtnListener btnListener = new BtnListener();
        btnOk.setActionCommand("Add");
        btnOk.addActionListener(btnListener);
        btnCancel.setActionCommand("Cancel");
        btnCancel.addActionListener(btnListener);
        //create the panel to add the buttons.
        JPanel buttonPanel = new JPanel();
        //add the buttons to the buttonPanel.
        buttonPanel.add(btnOk);
        buttonPanel.add(btnCancel);
        return buttonPanel;
    }

    public static void clearFields() {
        //get the components in textFieldPanel
        Component[] components = textFieldPanel.getComponents();
        JTextField jtf = new JTextField();
        //for each component in components
        for (Component component : components) {
            //if component is instance of JTextField
            if (component.getClass().equals(jtf.getClass())) {
                //clear text field text.
                jtf = (JTextField) component;
                jtf.setText("");
            }
        }
    }
}

Este JFrame eu criei na mão mesmo…

o que eu quero saber é:

existe algum padrão de projeto para transporte de dados entre a camada de visualização?

pq eu tentei da seguinte forma:

criei um objeto estático Movie, dentro do próprio JFrame, que vai receber os dados do filme.

Mas o problema é que ao ser dado um “dispose()” no JFrame não tem como eu manter os dados do filme armazenado na memória para posterior uso em outro JFrame.

Não sei se sou burro demais ou o q… mas não consegui pensar numa saída para essa situação.

quem puder me dar alguma dica de como padronizar o transporte de dados para que todos os frames possam utilizá-los fico grato.

Obs.1: Os dados devem ficar armazenados em memória durante a execução do programa, estou descartando o uso de banco de dados pq tipo assim eu quero fazer com q o sistema gere telas com base em informações geradas dinamicamente.

Obs.2: Eu uso o padrão MVC. Então estou falando somente da camada View do sistema, nada de envolver a camada Model.

6 Respostas

MarcioCasteloBranco

Bom amigo tenta passar pelo construtor quando vc estiver trabalhando com objetos graficos (gui && awt) todo o meio de referencia ao objeto e feita pelo construtor.
Vlw

ViniGodoy

isso não ajuda?
http://www.guj.com.br/posts/list/55710.java#292687

Se não puder usar o JDialog, você pode usar o padrão observer, ou implementar um mecanismo de troca de mensagens. Mas fica bem mais complicado.

valmirknasel

MarcioCasteloBranco:
Bom amigo tenta passar pelo construtor quando vc estiver trabalhando com objetos graficos (gui && awt) todo o meio de referencia ao objeto e feita pelo construtor.
Vlw

A idéia de passar o objeto pelo construtor já havia me ocorrido. Mas deixa eu especificar melhor meu problema:

Tenho um frame onde são visualizados alguns filmes cadastrados no sistema - DadosDoFilmeView, cujos estão carregados apenas em memória. Antes de salvar esses filmes, o usuário tem a possibilidade de adicionar mais alguns filmes à lista (DadosDoFilmeView). Para isso, abre-se outro frame (CadastrarNovoFilmeView), cujo receberá os dados de cadastro de um filme. Essa operação poderá se repetir enquanto o usuário quiser acrescentar mais filmes à lista. E ao inserir um novo filme, este deve constar imediatamente no frame DadosDoFilmeView. A exemplo, um frame com um jTable que é atualizado cada vez que for inserido um novo filme a lista atual de filmes. Eu queria fazer isso sem nenhuma “gambiarra”, quer dizer, “adaptação técnica”.

ViniGodoy

Nesse caso só usando o observer mesmo. Seu frame CadastrarNovoFilmeView deve disparar um evento, e o DadosDoFilmeView deve escutar por esse evento.

O primeiro passo é criar uma interfaces:
public interface CadastrarNovoFilmeViewListener {
    void filmeAdded(DadosDoFilmeEvent evt);
}

Crie então um evento:

public DadosDoFilmeEvent extends EventObject {
    private Filme filme;

    public DadosDoFilmeEvent(Filme filme) {
        this.filme = filme;
    }

    public Filme getFilme() { return filme; }
}

Crie no CadastrarNovoFilmeView, crie o suporte ao evento:

public class CadastrarNovoFilmeView {
    private Set<CadastrarNovoFilmeViewListener> listeners = new HashSet<CadastrarNovoFilmeViewListener>();

    public void fireFilmeAdded(Filme filme) {
        DadosDoFilmeEvent evt = new DadosDoFilmeEvent(filme);
        for (CadastrarNovoFilmeViewListener listener : listeners) {
            listener.filmeAdded(evt);
        }
    }

    public void addListener(CadastrarNovoFilmeViewListener listener) {
        listeners.add(listener);
    }

    public void removeListener(CadastrarNovoFilmeViewListener listener) {
        listeners.remove(listener);
    }
}

Após o cadastro de um novo filme, basta chamar o método fireFilmeAdded para avisar a todos os listeners que aquilo ocorreu.

Finalmente, faça a outra janela escutar esse evento, e se atualizar sempre que um evento chegar.

valmirknasel

ViniGodoy:
Nesse caso só usando o observer mesmo. Seu frame CadastrarNovoFilmeView deve disparar um evento, e o DadosDoFilmeView deve escutar por esse evento.

private Set<CadastrarNovoFilmeViewListener> listeners = new HashSet<CadastrarNovoFilmeViewListener>();

Desculpa a minha ignorância… mas pra q serve o HashSet??? Não entendi qual a função dele!!

Mas eu vou tentar implementar sua solução. Qualquer coisa eu posto outras dúvidas!!!

Obrigado pela atenção dedicada a mim!!!

O mundo é daquele que ajuda ao próximo e sempre haverá outro para retribuir ajudando-o de alguma forma!!!

ViniGodoy

Ele guarda os listeners. A vantagem de usa-lo é que ele não permite que o mesmo listener seja adicionado 2 vezes (e receba o evento duplicado). A desvantagem é que não há garantia de ordem, isto é, o primeiro a se registrar na lista não é necessáriamente o primeiro a receber o evento.
Geralmente, essa ordem não é importante mesmo. Se precisar garanti-la use um LinkedHashSet ao invés de um HashSet.

Criado 12 de março de 2010
Ultima resposta 15 de mar. de 2010
Respostas 6
Participantes 3