Como saber se um JFrame está aberto?

14 respostas
K

Olá pessoal,

Que código devo usar para saber se um determinado JFrame está aberto ou não? Alguém aí poderia me ajudar?

Obrigado a todos.

14 Respostas

A

verifique a propriedade “visible”.

Abraço,

Armando

K

Certo, mas se eu fizer isto:

MeuForm x = new MeuForm(); if ( x.isVisible() ) { ....código }

Acima estaria instanciando novamente o form, sendo que na realidade ele já foi instanciado. Veja que o MeuForm está por baixo. Então, no Form que está por cima, eu peciso detectar o MeuForm, saber se ele está aberto. O código que eu postei acima não funciona (compila mas não me retorna nada - vai sempre informar que o form não está visível).

Como é que eu percorro uma coleção de forms abertos? Não tem jeito???

Obrigado.

D

Não lembro de ter visto nenhum lugar que guarde essa coleção de forms instanciados.

Para fazer isso, vc teria que manualmente criar essa coleção e ir adicionando nela os forms.

Outro jeito, você precisa manter em algum lugar uma referência para o form em uma variável. Por exemplo:

public class Main {
   JFrame login;
   JFrame cadastro;

   public Main() {
      login = new LoginForm();
      cadastro = new CadastroForm();
   }

   // aí em algum método vc pode fazer isso
   if (login.isVisible()) {
      ....código
   }
}

e por aí vai

flw

K

Pois é.
Mas tenta fazer isto que está propondo (o código abaixo que vc mesmo postou), EM UMA OUTRA CLASSE (DENTRO DE UM OUTRO JFRAME):

// aí em algum método vc pode fazer isso if (login.isVisible()) { ....código }

não funciona!!!

D

Bom, aí você precisa de um meio de acessar o atributo de uma classe em uma outra certo, então você deve implementar um getLogin() nessa classe que eu escrevi, retornando o JFrame, e aí na outra classe:

if (instanciaDeMain.getLogin().isVisible()) { ....código }

Agora vai… :slight_smile:

K

Ahh, entendi - agora tá tudo claro!

Quer dizer que eu posso implementar um método getLogin(), por exemplo, no formulário do fundo, assim:

public void getLogin() { String Nome_usuario = txtUsu.getText(); String Senha_usuario = txtSenha.getText(); }

Depois eu posso abrir um novo formulário, (por cima do que está no fundo), e, dentro dele, capturar o Nome_usuario e a Senha_usuario, assim:

FormFundo x = new FormFundo() { x.Nome_usuario .......... x.Senha_usuario ......... }

Ainda não testei, mas agora me veio a mesma dúvida: Não foi criado uma nova instancia do Form??? está me parecendo que as duas variáveis ficarão nulas…
Veja se é isto mesmo.

Obrigado pelas dicas, sou meio novato.

K

Acabei de testar… como eu previa - não funciona!!!

Na realidade o que eu quero é percorrer os componentes do formulário do fundo, acessando suas propriedades, além, é claro, das propriedades do próprio form, como por exemplo, saber se ele está visível ou não. (Eu já sei que podemos passar variáveis na instanciação de um form, quando utilizamos o método setVisible() = true, mas eu não queria fazer assim, inclusive utilizei uma gambiarra ali com uma variável boolean para saber se o form está visível ou não - mas isto é gambiarra!).

Imagine que você tenha um código no segundo formulário, mas este código só poderá funcionar se o formulário do fundo estiver visível, caso contrário emitiria um aviso.

É só isto -
Talvez agora eu tenha sido um pouco mais claro. Se puder me ajudar…
Obrigado.

D

Olá

Ainda não testei, mas agora me veio a mesma dúvida: Não foi criado uma nova instancia do Form??? está me parecendo que as duas variáveis ficarão nulas…
Veja se é isto mesmo.

Bom, você mesmo se respondeu hehehe. Ali você criou outra instância, mas precisa da instância já criada do formulário de fundo, certo? Então, o que você vai precisar fazer, é passar de algum modo a instância do seu formulário de fundo para o novo formulário.

Você pode fazer isso pelo construtor do 2º formulário, algo como:

JFrame loginForm; // em LoginForm vc cria um construtor para receber o formulário de fundo e colocar em alguma propriedade dele loginForm = new LoginForm(formFundo); loginForm.setVisible(true);

Ou via um setFormularioFundo() na classe LoginForm desse meu exemplo, que faria a mesma coisa, colocar numa propriedade da classe o formulário.

Aí, para acessar os componentes, ou eles devem ser públicos, ou vc cria os get/set pra cada um que você quer acessar.

flw

K

Ok, mass… você poderia me mandar um exemplo real disto? me desculpa, mas ainda estou caminhando em java. É que eu fazia isto passando os dados para o segundo formulário em um vetor, só que isto é muito trabalhoso, e está me parecendo uma gambiarra também.

Obrigado.

D

ok, veja se isto clareia suas idéias:

package teste;

import java.awt.BorderLayout;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;

public class TesteJanela1 extends JFrame {
	private static final long serialVersionUID = 1L;

	JTextField campo;

	public String getCampo() {
		return campo.getText();
	}

	public TesteJanela1() {
		super("Pai");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		campo = new JTextField(10);
		getContentPane().add(campo, BorderLayout.CENTER);
		JButton b = new JButton("Click");
		b.addActionListener(new AbstractAction() {
			private static final long serialVersionUID = 1L;

			public void actionPerformed(java.awt.event.ActionEvent e) {
				new TesteJanela2((TesteJanela1) ((JButton) e.getSource()).getTopLevelAncestor()).setVisible(true);
			};
		});
		getContentPane().add(b, BorderLayout.SOUTH);
		pack();
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		TesteJanela1 teste = new TesteJanela1();
		teste.setVisible(true);
	}
}
package teste;

import javax.swing.JFrame;
import javax.swing.JLabel;


public class TesteJanela2 extends JFrame {
	private static final long serialVersionUID = 1L;
	TesteJanela1 pai;
	/**
	 * @param pai
	 */
	public TesteJanela2(TesteJanela1 pai) {
		super("Filho");
		this.pai = pai;
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		getContentPane().add(new JLabel(pai.getCampo()));
		pack();
	}
}
D

só não sei se esse seria o melhor jeito de fazer essas coisas… talvez criar um bean que represente cada campo no form e aí passar esse bean no construtor da outra classe talvez seja melhor… veja o que o pessoal mais experiente acha disso.

flw

K

Obrigado,
Era isto mesmo que eu precisava.
té mais…

V

Knik, seu problema parece que já foi resolvido, porém, vou responder essa tua pergunta acima e aproveitar nela pra fazer uma pergunta minha que estou com dúvida.

Tem como percorrer uma coleção de forms abertos sim, vc só precisa saber aonde ele foi aberto. O meu exemplo abaixo é com internal frame, basta vc aplicar em frame.

private void miFuncionariosActionPerformed(java.awt.event.ActionEvent evt) {                                               
        boolean exists=false;
        for(Component c : dpPrincipal.getComponents()){
            if(c instanceof ifFuncionarios){
                c.setVisible(true);
                c.transferFocus();
                exists=true;
            }
        }
        if(!exists){
            dpPrincipal.add(new ifFuncionarios());
        }

    }

No código acima eu quero abrir o internal frame ifFuncionarios, mas antes eu dou um getComponents() no meu DesktopPanel, que é onde eu adiciono os components, para pegar todos os Components que lá estão. E testo um por um para saber se algum é uma instancia de ifFuncionarios.
Se nenhum for, então eu abro.

Esse código funcionou perfeitamente, mas falha em um momento. Quando meu internal frame está minimizado ele o não encontra no getComponents e abre outro. Alguém pode me ajudar ?

V

Galera, resolvi o meu problema acima, e melhorei algumas coisas que não estavam funcionando nesse código aê.

Vou postar para vocês, para que se alguêm precisar fazer algo parecido, aí estará:

private void miFuncionariosActionPerformed(java.awt.event.ActionEvent evt) {                                               
        boolean exists=false;
        for(JInternalFrame f : dpPrincipal.getAllFrames()){
            if(f instanceof ifFuncionarios){
                if(f.isIcon()){
                    dpPrincipal.getDesktopManager().deiconifyFrame(f);
                }
                dpPrincipal.moveToFront(f);
                dpPrincipal.getDesktopManager().activateFrame(f);
                f.setLocation((dimTela.width-f.getWidth())/2, (dimTela.height-f.getHeight())/2);
                f.setVisible(true);
                exists=true;
            }
            
        }
        
        if(!exists){
            ifFuncionarios f = new ifFuncionarios();
            dpPrincipal.add(f);
            f.setLocation((dimTela.width-f.getWidth())/2, (dimTela.height-f.getHeight())/2);
            dpPrincipal.moveToFront(f);
            dpPrincipal.getDesktopManager().activateFrame(f);
        }

    }

O método getAllFrames() dos DesktopPanels pegam todos os internal frames inclusive aqueles que estão iconificados.
Daí o restante do código é só pra de-iconificar(restaurar) a janela e ajeitá-la.

Qualquer dúvida, postem aê.
Espero que tenha ajudado.

Vinicius Nogueira

Criado 10 de julho de 2006
Ultima resposta 21 de fev. de 2008
Respostas 14
Participantes 4