JInternalFrame - Fecha e não abre mais ;(

17 respostas
J

Saudações novos amigos do Fórum.

Comecei a estudar a Java faz uns meses já. E estou com um problema pra criar minha GUI.
Tenho um JFrame e nele um JDesktopPanel onde estão inclusos 3 JInternalFrames. (Detalhe estou usando o netbeans e não sei como acessar estes códigos.)
Criei um JMenuBar com um JMenu que tem 3 JMenuItem. Ao clicar em um deles pra abrir um JInternalFrame ele é exibido perfeitamente porque não estava visível e no código de ação do evento eu tenho:

private void itemMenuNovoActionPerformed(java.awt.event.ActionEvent evt) {                                             
         internalFrameRegister.setVisible(true);
    }

Mas quando este JInternal Frame é fechado, “xiiiiiiiii” ai tento abrí-lo novamente e ele não exibe. Creio que isso seja porque o objeto foi destruído. E agora? Não sei como fazer pra o JInternalFrame ser exibido novamente com os mesmos atributos(JLabel, JButton, JTextField) do que foi fechado.
Como estou fazendo no Netbeans setei nas propriedades do JInternalFrame o atributo defaultCloseOperation para DISPOSE.

Galerinha aguardo algum retorno de vocês.
Abraço e grato pela ajuda. :stuck_out_tongue:

17 Respostas

V

Não faz o menor sentido, deveria abrir normalmente. Poste seu código.
Verifique também se não há nenhuma exception sendo disparada.

J

Godoy, o código tá meio extenso. =/
Não precisa ler ele todo nao. =/

public class MainFrame extends javax.swing.JFrame {

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

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        desktopPanel = new javax.swing.JDesktopPane();
        internalFrameEdit = new javax.swing.JInternalFrame();
        labelTitleEditContact = new javax.swing.JLabel();
        panelDataEntered2 = new javax.swing.JPanel();
        labelContactNameSearch = new javax.swing.JLabel();
        contactNameSearch = new javax.swing.JTextField();
        buttonSearch = new javax.swing.JButton();
        panelDataEntered3 = new javax.swing.JPanel();
        labelContactNameEdited = new javax.swing.JLabel();
        contactNameEdited = new javax.swing.JTextField();
        labelContactNumberEdited = new javax.swing.JLabel();
        contactNumberEdited = new javax.swing.JTextField();
        buttonSalvar2 = new javax.swing.JButton();
        internalFrameDelete = new javax.swing.JInternalFrame();
        internalFrameRegister = new javax.swing.JInternalFrame();
        labelTitleRegisterContact = new javax.swing.JLabel();
        panelDataEntered = new javax.swing.JPanel();
        labelContactName = new javax.swing.JLabel();
        contactName = new javax.swing.JTextField();
        labelContactNumber = new javax.swing.JLabel();
        contactNumber = new javax.swing.JTextField();
        buttonSalvar = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        menuArquivo = new javax.swing.JMenu();
        intemMenuFechar = new javax.swing.JMenuItem();
        menuExibir = new javax.swing.JMenu();
        menuOpcoes = new javax.swing.JMenu();
        itemMenuNovo = new javax.swing.JMenuItem();
        itemMenuEditar = new javax.swing.JMenuItem();
        itemMenuExcluir = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Agenda Eletronica");
        setBounds(new java.awt.Rectangle(0, 0, 0, 0));
        setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        setResizable(false);

        desktopPanel.setBackground(new java.awt.Color(204, 204, 204));

        internalFrameEdit.setClosable(true);
        internalFrameEdit.setIconifiable(true);
        internalFrameEdit.setTitle("Editar Contato");
        internalFrameEdit.setNormalBounds(new java.awt.Rectangle(0, 20, 350, 120));
        internalFrameEdit.setVisible(true);
        internalFrameEdit.getContentPane().setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 5, 10));

        labelTitleEditContact.setFont(new java.awt.Font("Tahoma", 0, 16)); // NOI18N
        labelTitleEditContact.setForeground(new java.awt.Color(51, 153, 255));
        labelTitleEditContact.setText("Digite o nome do contato");
        internalFrameEdit.getContentPane().add(labelTitleEditContact);

        panelDataEntered2.setLayout(new java.awt.GridLayout(1, 0, 5, 5));

        labelContactNameSearch.setText("Nome do contato:");
        panelDataEntered2.add(labelContactNameSearch);

        contactNameSearch.setAutoscrolls(false);
        panelDataEntered2.add(contactNameSearch);

        buttonSearch.setText("Buscar");
        panelDataEntered2.add(buttonSearch);

        internalFrameEdit.getContentPane().add(panelDataEntered2);

        panelDataEntered3.setMinimumSize(new java.awt.Dimension(170, 79));
        panelDataEntered3.setLayout(new java.awt.GridLayout(3, 2, 5, 5));

        labelContactNameEdited.setText("Nome do Contato:");
        panelDataEntered3.add(labelContactNameEdited);

        contactNameEdited.setEditable(false);
        contactNameEdited.setEnabled(false);
        panelDataEntered3.add(contactNameEdited);

        labelContactNumberEdited.setText("Telefone do Contato:");
        panelDataEntered3.add(labelContactNumberEdited);

        contactNumberEdited.setEditable(false);
        contactNumberEdited.setEnabled(false);
        panelDataEntered3.add(contactNumberEdited);

        buttonSalvar2.setText("Salvar");
        buttonSalvar2.setEnabled(false);
        panelDataEntered3.add(buttonSalvar2);

        internalFrameEdit.getContentPane().add(panelDataEntered3);

        internalFrameEdit.setBounds(50, 40, 350, 220);
        desktopPanel.add(internalFrameEdit, javax.swing.JLayeredPane.DEFAULT_LAYER);

        internalFrameDelete.setClosable(true);
        internalFrameDelete.setIconifiable(true);
        internalFrameDelete.setMaximizable(true);
        internalFrameDelete.setResizable(true);
        internalFrameDelete.setPreferredSize(new java.awt.Dimension(300, 240));

        javax.swing.GroupLayout internalFrameDeleteLayout = new javax.swing.GroupLayout(internalFrameDelete.getContentPane());
        internalFrameDelete.getContentPane().setLayout(internalFrameDeleteLayout);
        internalFrameDeleteLayout.setHorizontalGroup(
            internalFrameDeleteLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 284, Short.MAX_VALUE)
        );
        internalFrameDeleteLayout.setVerticalGroup(
            internalFrameDeleteLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 211, Short.MAX_VALUE)
        );

        internalFrameDelete.setBounds(140, 110, 300, 240);
        desktopPanel.add(internalFrameDelete, javax.swing.JLayeredPane.DEFAULT_LAYER);

        internalFrameRegister.setClosable(true);
        internalFrameRegister.setIconifiable(true);
        internalFrameRegister.setTitle("Cadastrar Novo");
        internalFrameRegister.getContentPane().setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 5, 25));

        labelTitleRegisterContact.setFont(new java.awt.Font("Tahoma", 0, 16));
        labelTitleRegisterContact.setForeground(new java.awt.Color(0, 153, 255));
        labelTitleRegisterContact.setText("Registro de um novo contato");
        internalFrameRegister.getContentPane().add(labelTitleRegisterContact);

        panelDataEntered.setLayout(new java.awt.GridLayout(3, 2, 0, 5));

        labelContactName.setText("Nome do Contato:  ");
        panelDataEntered.add(labelContactName);
        panelDataEntered.add(contactName);

        labelContactNumber.setText("Telefone do Contato:  ");
        panelDataEntered.add(labelContactNumber);
        panelDataEntered.add(contactNumber);

        buttonSalvar.setText("Salvar");
        panelDataEntered.add(buttonSalvar);

        internalFrameRegister.getContentPane().add(panelDataEntered);

        internalFrameRegister.setBounds(160, 10, 350, 190);
        desktopPanel.add(internalFrameRegister, javax.swing.JLayeredPane.DEFAULT_LAYER);

        menuArquivo.setText("Arquivo");

        intemMenuFechar.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.CTRL_MASK));
        intemMenuFechar.setText("Fechar");
        menuArquivo.add(intemMenuFechar);

        menuBar.add(menuArquivo);

        menuExibir.setText("Exibir");
        menuBar.add(menuExibir);

        menuOpcoes.setText("Opcoes");

        itemMenuNovo.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.ALT_MASK));
        itemMenuNovo.setText("Novo");
        itemMenuNovo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemMenuNovoActionPerformed(evt);
            }
        });
        menuOpcoes.add(itemMenuNovo);

        itemMenuEditar.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.ALT_MASK));
        itemMenuEditar.setText("Editar");
        itemMenuEditar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                itemMenuEditarActionPerformed(evt);
            }
        });
        menuOpcoes.add(itemMenuEditar);

        itemMenuExcluir.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_X, java.awt.event.InputEvent.ALT_MASK));
        itemMenuExcluir.setText("Excluir");
        menuOpcoes.add(itemMenuExcluir);

        menuBar.add(menuOpcoes);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(desktopPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 651, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(desktopPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 0, Short.MAX_VALUE)
                .addContainerGap())
        );

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-667)/2, (screenSize.height-494)/2, 667, 494);
    }// </editor-fold>//GEN-END:initComponents

    private void itemMenuNovoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemMenuNovoActionPerformed
         internalFrameRegister.setVisible(true);
    }//GEN-LAST:event_itemMenuNovoActionPerformed

    private void itemMenuEditarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_itemMenuEditarActionPerformed
        internalFrameEdit.setVisible(true);
    }//GEN-LAST:event_itemMenuEditarActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new MainFrame().setVisible(true);    
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton buttonSalvar;
    private javax.swing.JButton buttonSalvar2;
    private javax.swing.JButton buttonSearch;
    private javax.swing.JTextField contactName;
    private javax.swing.JTextField contactNameEdited;
    private javax.swing.JTextField contactNameSearch;
    private javax.swing.JTextField contactNumber;
    private javax.swing.JTextField contactNumberEdited;
    private javax.swing.JDesktopPane desktopPanel;
    private javax.swing.JMenuItem intemMenuFechar;
    private javax.swing.JInternalFrame internalFrameDelete;
    private javax.swing.JInternalFrame internalFrameEdit;
    private javax.swing.JInternalFrame internalFrameRegister;
    private javax.swing.JMenuItem itemMenuEditar;
    private javax.swing.JMenuItem itemMenuExcluir;
    private javax.swing.JMenuItem itemMenuNovo;
    private javax.swing.JLabel labelContactName;
    private javax.swing.JLabel labelContactNameEdited;
    private javax.swing.JLabel labelContactNameSearch;
    private javax.swing.JLabel labelContactNumber;
    private javax.swing.JLabel labelContactNumberEdited;
    private javax.swing.JLabel labelTitleEditContact;
    private javax.swing.JLabel labelTitleRegisterContact;
    private javax.swing.JMenu menuArquivo;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenu menuExibir;
    private javax.swing.JMenu menuOpcoes;
    private javax.swing.JPanel panelDataEntered;
    private javax.swing.JPanel panelDataEntered2;
    private javax.swing.JPanel panelDataEntered3;
    // End of variables declaration//GEN-END:variables
}
Eu fiz um teste agora, para quando o user clicar no JMenuItem(itemMenuNovo) pra criar um novo contato com nome e telefone o evento faz o seguinte:
private void itemMenuNovoActionPerformed(java.awt.event.ActionEvent evt) {                                             
         desktopPanel.add(internalFrameRegister); //Adiciona ao desktopPanel o JInternalFrame que contem o formulário.
         internalFrameRegister.setVisible(true); //Seta a visibilidade para true
    }
(Detalhe: antes de eu testar isso, eu só tinha setado a visibilidade pra true.) NO primeiro clique no 'itemMenuNovo' para criar um novo contato ele lança uma exception. E quando clico denovo ele abre o JInternalFrame :evil: A exceção é na linha que eu adiciono ao desktopPanel: Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: illegal component position.

Abraço

M

acontece que o evento do menu que vc clica faz com que ele fique visivel, na primeira vez beleza, porem quando vc fecha ele o objeto é descarregado da memoria e se perde. oq vc tem q fazer é criar o objeto dentro do envento em vez de colocar somente o setVisible nele entende.
tipo assim:

SeuInternalFrame f = new SeuInternalFrame(); // ele sempre vai criar um novo e quando fechar ele é descartado
setVisible(true);

J

Saquei o que vc disse. Eu havia tentado fazer isso.
Só que eu teria que pegar todo o código que o nebeans gera pra criar o meu objeto JInternalFrame.
E vendo a longo prazo, se eu precisar isso com outros Internals Frames sempre vou ter que pegar o código q o Netbeans gera pra botar dentro do evento. Isso seria uma grande perca de tempo. Se houvesse uma maneira de ja criar dentro do evento atraves do netbeans =/

=/
Entendeu o q eu disse?
Mas eu entendi perfeitamente o que vc quis dizer.

Grato =D

M

na verdade vc nao precisa colocar todo o codigo dentro do evento, vc so precisa chamar o codigo de lah. se vc quer reaproveitar coloque o codigo dentro de uma classe separada e chama ela sempre que necessario.

V

Não tem nada a ver com ser ou não ser descarregado da memória. Em java, nada é descarregado da memória, a menos que vc limpe as referências a um objeto, o que você não faz em seu código (se fizesse, o erro seria NullPointerException).

Isso provavelmente é um erro de algum componente tendo o layout ajustado de maneira errada. Geralmente são erros difíceis de encontrar e a solução é mesma que o Mauricio falou: criar um novo JInternalFrame.

M

Godoy, quando vc fecha um JInternalFrame ele nao limpa as referencias do objeto?

J

Beleza, tentei aqui e o JInternalFrame é aberto.
Porém, quando digito algo nos TextFields e fecho o JInternalFrame deixando os TextFields com texto. Quando novamente vou ao JMenuItem pra chamar o JInternalFrame ele abre mas vem com os textos que eu tinha digitado isso não era pra acontecer porque o defaultCloseOperation está DISPOSE.
E se ele estando aberto e eu tentar abrí-lo denovo ele gera uma exception -> Exception in thread “AWT-EventQueue-0” java.lang.IllegalArgumentException: illegal component position

Abraço!

V

Não da forma que ele está fazendo. Note que ele mantém uma variável apontando para o JInternalFrame chamada internalFrameRegister. Ela vai manter o internal frame vivo.

J

Gente eu nao eendi ntporque que ao clicar a primeira vez é lançada uma exceção. E na segunda vez que clico o JInternalFrame é aberto.

Esse problema tá persistindo. =/

E

Faz assim:

No seu método itemMenuNovoActionPerformed, inverte a ordem lá. primeiro seta o form como visivel e depois adiciona ele ao JDesktopPane.
Acredito que deva funcionar. (Apesar de não fazer muito sentido nesse erro)

J

Nem deu certo =/
Lança a exceção da mesma forma.

E

Eu executei seu código aqui e realmente estava dando erro.
Eu percebi tbem que vc já está adicionando o JInternalFrame já na sua tela principal.
Se vc tirar os JInternalframe, o erro deixa de existir.

Crie um novo Form Swing Interno (JInternalFrame) e instancie vc mesmo. Não é muito aconselhável vc colocar TODOS os componentes da sua aplicação pesando no Frame Principal.

J

Entendi, então neste caso o Netbeans possui algo que permita a não criação de todos os componentes na Classe Principal?

Acabei de testar aquia sua solução e deu certo. Declarei todas as variáveis e instancia das mesmas dentro do Evento gerado.
Assim a Janela sempre será aberta ao ser fechada.

Mas ainda ficou na minha cabeça uma duvidazinha com relação ao desempenho. Tipo, sempre ao fechar o internalFrameRegister os objetos criados dentro do evento serão perdidos? Ou serão atribuidos novos objetos as variaveis que são lá definidas?

Abraço. E muito obrigado por me ajudar ae galera.
Principalmente à Eliangela :smiley:

V

São perdidos e eles são recriados. Mas tudo bem, a menos que vc esteja vendo um form ser desenhado, não se preocupe com isso. Essa forma também poupa memória, já que manter a variável internalFrameRegister vai manter o frame na memória mesmo que ele não esteja sendo usado.

Em otimização, sempre temos que balancear processador vs. uso de memória.

J

Entendi!
Mas como ele é mantido na memória? Eu acho que a variável internalFrameRegister é destruída e nao mantida porque o atributo defaultCloseOperation está como DISPOSE.

Godoy você poderia me explicar mais sobre isso? em relação a este caso.

Grato.

E

Os componentes da janela principal (menus, botões, etc) é importante serem declarados e inicializados na inicialização da janela.
As outras janelas é importante colocar cada janela em cada classe diferente, para que essas classes inicializem seus próprios componentes.

Agora imagine vc fazendo um sistema que tem uma janela principal e outras 50 janelinhas. Agora imagine essas janelinhas sendo carregadas junto com a Janela Principal… a inicialização do programa ficaria muito pesada.

JanLuckas:
Entendi!
Mas como ele é mantido na memória? Eu acho que a variável internalFrameRegister é destruída e nao mantida porque o atributo defaultCloseOperation está como DISPOSE.

Godoy você poderia me explicar mais sobre isso? em relação a este caso.

Grato.

O dispose não tira o objeto da memória. O objeto só é retirado da memória se vc atribuir null a ele.
O dispose apenas libera os recursos nativos usados pela classe Window, liberando memória, e a janela é marcada como undisplayable (invisível).
Se vc usar o método setVisible(true) no seu objeto Window (no mesmo objeto) ele vai mostrar a mesma janela, como vc tinha deixado antes de dar dispose.

Caso vc queira sempre mostrar uma nova janela, vc deve instanciar o seu objeto Window cada vez que vc quiser que ela apareça.

Criado 20 de junho de 2011
Ultima resposta 22 de jun. de 2011
Respostas 17
Participantes 4