JDesktopPane e JInternalFrame

Olá Pessoal, estou com uma duvida
Quando eu clico num botão para chamar a uma tela do tipo JInternalFrame ela abre normalmente da forma que eu quero, porém quando eu a fecho e clico no botão novamente ela não abre mais.
como posso solucionar essa dificuldade?

package CC01_JFrame02;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Exemplo06JDesktopPane extends JFrame implements ActionListener{
	JInternalFrame if1, if2, if3;
	JPanel p1, p2, p3;
	JDesktopPane dt;
	JMenuBar menu;
	JMenu menuFuncao, menuCadastrar, menuRelatorio;
	JMenuItem itemCliente, itemFornecedor, itemSair, itemRelat1, itemRelat2;
	
	public Exemplo06JDesktopPane(){
		setSize(800, 600);
		setTitle("Minha primeira aplicação Java");
		setLocationRelativeTo(null); //Abrir aplicacao no centro da tela
		setUndecorated(true);
		getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
		getRootPane().setBorder(BorderFactory.createEtchedBorder(0));
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		
		menu = new JMenuBar();
		
		menuFuncao = new JMenu("Arquivo");
		itemSair = new JMenuItem("Sair");
		itemSair.addActionListener(this);
		menuFuncao.add(itemSair);
		
		menuCadastrar = new JMenu("Cadastrar");
		itemCliente = new JMenuItem("Cliente");
		itemCliente.addActionListener(this);
		menuCadastrar.add(itemCliente);
		itemFornecedor = new JMenuItem("Fornecedor");
		itemFornecedor.addActionListener(this);
		menuCadastrar.add(itemFornecedor);
		
		menuRelatorio = new JMenu("Relatorio");
		itemRelat1 = new JMenuItem("Relatorio I");
		menuRelatorio.add(itemRelat1);
		itemRelat2 = new JMenuItem("Relatorio II");
		menuRelatorio.add(itemRelat2);
		
		setJMenuBar(menu);
		menu.add(menuFuncao);
		menu.add(menuCadastrar);
		menu.add(menuRelatorio);
		
		if1 = new JInternalFrame("Cadastro Cliente", false, true, false, false);
		if1.setBounds(200, 150, 400, 280);
		p1 = new JPanel();
		p1.setBounds(5, 5, 380, 235);
		if1.getContentPane().setLayout(null);
		if1.getContentPane().add(p1);
		if1.setVisible(false);
		
		if2 = new JInternalFrame("Cadastro Fornecedor", false, true, false, false);
		if2.setBounds(200, 150, 400, 280);
		p2 = new JPanel();
		p2.setBounds(5, 5, 380, 235);
		if2.getContentPane().setLayout(null);
		if2.getContentPane().add(p2);
		if2.setVisible(false);
				
		dt = new JDesktopPane();
		dt.setLayout(null);
		dt.add(if1);
		dt.add(if2);
		
		getContentPane().add(dt);
	}
	
	public void actionPerformed(ActionEvent e){
		if(e.getSource() == itemSair){
			System.exit(0);
		}
		if(e.getSource() == itemCliente){
			if1.setVisible(true);
		}
		if(e.getSource() == itemFornecedor){
			if2.setVisible(true);
		}
	}
	
	public static void main(String args[]){
		new Exemplo06JDesktopPane().setVisible(true);
	}
}

Vc tem 2 alternativas:

  1. Setar a operação default do botão fechar como “ocultar”:
        if1.setDefaultCloseOperation(HIDE_ON_CLOSE);
        if2.setDefaultCloseOperation(HIDE_ON_CLOSE);

O padrão para os JInternalFrame’s é DISPOSE_ON_CLOSE, que libera todos os recursos gráficos do S.O. usados pela janela. Aí ela não responde mais.

Essa opção é útil quando vc quer preservar os dados digitados na janela entre uma exibição e outra.

  1. Dar new JInternalFrame(…) cada vez que vc for (re)abrir uma janela.

Cada vez que clicar em Cliente, é feito um new. Esta opção cria uma nova janela branquinha. Não use o HIDE_ON_CLOSE, senão pode haver um “resource leak” (vazamento de recursos), que é o estado em que vc instancia novas janelas, as velhas perdem a referência mas os recursos gráficos do S.O. continuam abertos.

Boa tarde MarkKnopfler
Muito obrigado pela ajuda, realmente a primeira opção é a melhor para o que eu estou fazendo.
Muito obrigado pela explicação tb, foi de grande ajuda
Abraço

Além do que o MarkKnopfler também utilizo desse método abaixo ao tentar abrir a janela

private void visualizarInternalFrame(JInternalFrame internal) { //dessa maneira a janela já vem selecionada como padrão internal.setVisible(false); internal.setVisible(true); try {//caso ele esteja minimizado então maximize-o internal.setIcon(false); } catch (PropertyVetoException ex) {} }

Esse código irá selecionar o JInternalFrame passado deixando ele em primeiro plano.

Muito bom Ivan Alves, obrigado pela dica