Usar uma instância de JInternalFrame em vez de criar outra instância

Oi,

estou precisando que um instância de JInternalFrame após ser criada seja usada toda que vez que se queira abrir uma nova instância do mesmo objeto.
Consegui realizar essa operação, mas acredito que possa haver um modo mais direto para o que eu pretendo.

Abaixo os fontes para uma avaliação:

// PrincipalFrame.java

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyVetoException;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;


public class PrincipalFrame extends JFrame {

   private JMenu menu;
   private JMenuItem menuItem1;
   private JMenuBar menuBar;
   private JDesktopPane desktop;   
   private Frame_1 frame1;
	   
   public PrincipalFrame () {
	super("Frame Principal");
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
        this.setBounds(100,50,650,600);  
        
        menuBar          = new JMenuBar();
        menu             = new JMenu("Frames");
        menuItem1        = new JMenuItem("Frame 1");
        menu.add(menuItem1);
        menuBar.add(menu);        
        this.setJMenuBar(menuBar);
        
        menuItem1.addActionListener(new ActionListener() 
            { 
             public void actionPerformed( ActionEvent event ) 
             {
               exibeFrame1();   
             }  
            } 
        ); 
                
        desktop = new JDesktopPane();
        this.setContentPane(desktop);

   }

   public static void main (String args[]) {
	new PrincipalFrame().setVisible(true);
   }
   
   public void exibeFrame1() {

      if ( frame1 == null ||                          // verifica se a instancia nao foi criada ou
         (! frame1.isDisplayable() && ! frame1.isIcon()  )) {  // nao esta "a mostra" e nao esta minimizado
            if ( frame1 != null) {
                frame1 = null;	
            }
            frame1 = new Frame_1();
            desktop.add(frame1);  
            frame1.setVisible(true);             
      } else
            frame1.alteraLabel();

      try {
         frame1.setSelected(true);
      } catch (PropertyVetoException ex) {
         ex.printStackTrace();
      } 

   }    
   
}	

//  Frame_1.java
 
import java.awt.Container;
import java.beans.PropertyVetoException;
import javax.swing.JButton;
import java.awt.FlowLayout;
import javax.swing.JLabel;
import javax.swing.JInternalFrame;

public class Frame_1 extends JInternalFrame{
    
    private static Integer nrFrame     = 1;   
    private static Integer nrFrame_aux ;  
    private static Integer nrAlteracoes = 0 ;  

    private JLabel label;   
    
    public Frame_1() {
        super("Novo Frame n. " + nrFrame , true, // resizable
			         true, // closable
			         true, // maximizable
			         true);// iconifiabl        
 
        Container cont = this.getContentPane();
        cont.setLayout(new FlowLayout(FlowLayout.CENTER));          

        label = new JLabel();
        label.setText("Texto no Frame nr. " + nrFrame);
        cont.add(label);

        nrFrame_aux = nrFrame; 
        ++nrFrame;

        this.setDefaultCloseOperation(this.DISPOSE_ON_CLOSE); 
        // this.pack(); 
        this.setSize(400, 400);
        
        
    }    
 
    public void alteraLabel() {

        label.setText("Alteracao nr " + ++nrAlteracoes + " no Label do Frame nr. " + nrFrame_aux);
    }      
    
}

Nesse exemplo, ao minimizar o frame interno e tentar abrir outra instância, não se outra outro frame, mas também não se maximiza o frame minimizado.

Se puder ajudar, agradeço.

Se eu entendi bem…

umas vez instanciado, o obejto fica nos bastidores esperando ser chamado. Você não pode abrir dois telas a partir de uma mesma instancia! Não ao mesmo tempo!

Sempre que postar códigos, use a tag code. Fica mais fácil de analisarmos. :wink:
Se não sabe fazer isso, lê aqui:
http://www.guj.com.br/posts/list/50115.java

  1. A solução é simples. Crie um mapa que associa a classe do seu frame ao frame aberto:

Map<Class<? extends JInternalFrame>, JInternalFrame> frames = new HashMap<Class<? extends JInternalFrame>, JInternalFrame>();

  1. Quando o usuário clicar para abrir um frame, verifique se ele está no mapa:
    2.1. Se estiver, pegue o internalpane do mapa e o torne visível, ele já foi aberto;
    2.2. Se não estiver, crie o internalpane, adicione-o ao mapa e torne-o visível;

Só isso. :slight_smile:

Quase entendi a solução.

Procurei informações sobre Map e descobri que é uma estrutura de dados. Agora eu preciso de mais informações para assimilar o comando proposto por você

Eu achei :
Map map = new HashMap();

    String key = "pri_chave";
    String value = "pri_value"l;

    map.put(key,value);

Mas dissecar todo aquele seu comando é muito para mim …

http://java.sun.com/docs/books/tutorial/collections/index.html
http://java.sun.com/developer/Books/javaprogramming/corejava/
http://www.informit.com/articles/article.aspx?p=368648
http://www.oracle.com/technology/pub/articles/maps1.html

Essa é a versão usando a estrutura de dados Map. Os links indicados falam sobre o básico dessa estrutura; não comentam o que é Class<? extends JInternalFrame>. Eu sei que é um tipo de dado; coloquei no seu lugar a instância do meu JInternalFrame. Mas fiquei sem entender o comando class .

// PrincipalFrame.java

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyVetoException;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;


public class PrincipalFrame extends JFrame {

   private JMenu menu;
   private JMenuItem menuItem1;
   private JMenuBar menuBar;
   private JDesktopPane desktop;   
   private Frame_1 frame1;
   public static PrincipalFrame principalFrame;
   public Map <Class<? extends JInternalFrame>, Frame_1> framesMap =  new HashMap<Class<? extends JInternalFrame>, Frame_1>();        
    
	   
   public PrincipalFrame () {
	super("Frame Principal");
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);  
        this.setBounds(100,50,650,600);  
        
        menuBar          = new JMenuBar();
        menu             = new JMenu("Frames");
        menuItem1        = new JMenuItem("Frame 1");
        menu.add(menuItem1);
        menuBar.add(menu);        
        this.setJMenuBar(menuBar);
        
        menuItem1.addActionListener(new ActionListener() 
            { 
             public void actionPerformed( ActionEvent event ) 
             {
               exibeFrame1();   
             }  
            } 
        ); 
                
        desktop = new JDesktopPane();
        this.setContentPane(desktop);

   }

   public static void main (String args[]) {
	principalFrame = new PrincipalFrame();
        principalFrame.setVisible(true);
   }
   
   public void exibeFrame1() {

      if ( framesMap.isEmpty() || ! framesMap.containsKey(frame1.getClass())) {
            frame1 = new Frame_1();
            framesMap.put(frame1.getClass(), frame1);
            desktop.add(frame1,javax.swing.JLayeredPane.DEFAULT_LAYER);  
            frame1.setVisible(true);             
      } else {
            frame1.alteraLabel();     
      }      
      try {
         frame1.setSelected(true);
      } catch (PropertyVetoException ex) {
         ex.printStackTrace();
      } 

   }    
   
}	
//  Frame_1.java
 
import java.awt.Container;
import javax.swing.JButton;
import java.awt.FlowLayout;
import javax.swing.JLabel;
import javax.swing.JInternalFrame;

public class Frame_1 extends JInternalFrame{
    
    private static Integer nrFrame     = 1;   
    private static Integer nrFrame_aux ;  
    private static Integer nrAlteracoes;

    private JLabel label;   
    
    public Frame_1() {
        super("Novo Frame n. " + nrFrame , true, // resizable
			         true, // closable
			         true, // maximizable
			         true);// iconifiabl        
        Container cont = this.getContentPane();
        cont.setLayout(new FlowLayout(FlowLayout.CENTER));          

        label = new JLabel();
        label.setText("Texto no Frame nr. " + nrFrame);
        cont.add(label);

        nrFrame_aux = nrFrame; 
        ++nrFrame;

        this.setDefaultCloseOperation(this.DISPOSE_ON_CLOSE); 
        // this.pack(); 
        
        this.addInternalFrameListener(new javax.swing.event.InternalFrameListener() {
            public void internalFrameActivated(javax.swing.event.InternalFrameEvent evt) {
            }
            public void internalFrameClosed(javax.swing.event.InternalFrameEvent evt) {
                formInternalFrameClosed(evt);
            }
            public void internalFrameClosing(javax.swing.event.InternalFrameEvent evt) {
            }
            public void internalFrameDeactivated(javax.swing.event.InternalFrameEvent evt) {
            }
            public void internalFrameDeiconified(javax.swing.event.InternalFrameEvent evt) {
            }
            public void internalFrameIconified(javax.swing.event.InternalFrameEvent evt) {
            }
            public void internalFrameOpened(javax.swing.event.InternalFrameEvent evt) {
            }
        });
        
        this.setSize(400, 400);
        nrAlteracoes = 0;
        
    }    
 
    public void alteraLabel() {

        label.setText("Alteracao nr " + ++nrAlteracoes + " no Label do Frame nr. " + nrFrame_aux);
    }     

    private void formInternalFrameClosed(javax.swing.event.InternalFrameEvent evt) {                                         
// TODO adicione seu código de manipulação aqui:
        PrincipalFrame.principalFrame.framesMap.remove(this.getClass());
    }                                        
    
}

Conclusão: não acredito que a versão acima seja melhor que a primeira. Precisei acrescentar no Frame_1.java, um comando “PrincipalFrame.principalFrame.framesMap.remove(this.getClass());” para poder fechá-lo e depois abri-lo novamente.
Como só tive a indicação do comando Map, talvez não tenha construído o código como a pessoa que sugeriu esse modo.