[DÚVIDA] Passagem de parâmetros entre classes GUI Swing

16 respostas
T

{primeira postagem minha aqui - até achei um tópico sobre isso, mas mesmo seguindo o que está la, nao consegui}

Uso o netbeans, tenho 2 arquivos GUI Swing (2 telas), estou tentando passar um parâmetro (uma string) de uma tela pra outra, por enquanto só quero aprender, na primeira tela tem um JTextField e um botão, na segunda tela tem apenas um JTextField.

Coloco a string na primeira tela e ao apertar o botão, gostaria que aparecesse na segunda tela.

criei um “Arquivo2 f = new Arquivo2();” na primeira tela, e no botão joguei um “f.show();”, ele mostra a segunda tela com o TextField vazio, pensei em fazer um
“Arquivo2 f = new Arquivo2(String visor);”, mas ele nao passa a string visor.

Após a decepção, criei um método:

public void passa (String visor)

{

Arquivo2 s = new Arquivo2(visor);

}

(só que nao sei chamar essa variavel “s” no botão)

Só quero um empurrãozinho rs

Valew !!!

16 Respostas

ViniGodoy

O tópico foi esse aqui?
http://www.guj.com.br/posts/list/55710.java#292687

Nesse tem um exemplo funcionando.

evertonsilvagomesjav
tsalsicha:
{primeira postagem minha aqui - até achei um tópico sobre isso, mas mesmo seguindo o que está la, nao consegui}

Uso o netbeans, tenho 2 arquivos GUI Swing (2 telas), estou tentando passar um parâmetro (uma string) de uma tela pra outra, por enquanto só quero aprender, na primeira tela tem um JTextField e um botão, na segunda tela tem apenas um JTextField.

Coloco a string na primeira tela e ao apertar o botão, gostaria que aparecesse na segunda tela.

criei um "Arquivo2 f = new Arquivo2();" na primeira tela, e no botão joguei um "f.show();", ele mostra a segunda tela com o TextField vazio, pensei em fazer um
"Arquivo2 f = new Arquivo2(String visor);", mas ele nao passa a string visor.

Após a decepção, criei um método:

"public void passa (String visor)
{
Arquivo2 s = new Arquivo2(visor);
}"

(só que nao sei chamar essa variavel "s" no botão)

Só quero um empurrãozinho rs

Valew !!!

Dentro do evento do seu botao passa ele pelo seu Construtor mesmo uai.

new TelaDois("minhaStringQueVaiViajar").setVisible(True);

Dentro da class TelaDois

String minhaString;

public TelaDois(String minhaStringViajante){

this.minhaString = minhaStringViajante;

// chama um metodo que seta no JLabel ou por aqui mesmo.

}
evertonsilvagomesjav

Desculpa Vini, não vi vc respondendo.

ViniGodoy

Ué, pode responder também, hehehe. :slight_smile:

evertonsilvagomesjav

Inclusive eu abri o link que vc passou e baixei as classes aqui pra olhar, qual que é a diferença de usar ou n aquele invokeLater()?

O netbeans gera isso nas classes tb que ja vi.

T

Tentei aqui, nada sublinhado, tudo “perfeito”, só que da erro quando clico no botão
NO ARQUIVO1

public class Arquivo1 extends javax.swing.JFrame {

String svisor1;

(coloquei isso antes do construtor)

no botão:

svisor1=visor1.getText(); //visor1 é o nome do JTextField

new Arquivo2(svisor1);

NO ARQUIVO 2

public class Arquivo2 extends javax.swing.JFrame {

String passada; 

public Arquivo2(String svisor1)
{
    this.passada=svisor1;

    visor2.setText(passada);
}

acho que cheguei BEM perto

ViniGodoy

Quando você cria uma aplicação Swing, o Swing dispara uma segunda thread. Essa thread, faz todo o processamento da interface gráfica: lê eventos, pinta componentes, etc.

Toda a atualização de tela (abrir janelas, alterar text fields, labels, etc.) deve, obrigatoriamente, ser feito pela thread do Swing. É uma regra do Swing, pois ele não é thread-safe.

Mas, se vc estiver em outra thread, como fazer para atualizar um componente Swing? Os projetistas da API criaram então uma fila de eventos. A thread do Swing sempre lê nessa fila se há algo para fazer. E então executa o que estiver na fila.

Os comandos EventQueue.invokeLater e EventQueue.invokeAndWait são comandos thread-safe que permite inserir nessa fila um “pedido” ao Swing. Por exemplo, o pedido para abrir uma nova janela, ou para atualizar o componente. E como você diz a ele o que você quer? Colocando o código a ser executado dentro de um Runnable. Note que esse runnable não irá disparar uma nova thread. Trata-se só de um trecho de código para ser executado na thread do Swing, nada mais.

Sincronizar métodos não é a única forma de garantir thread-safety. Outra forma é não fazer com que threads interajam, e criar uma comunicação entre elas através de uma fila de mensagens. Essa abordagem, além de mais simples, simplifica o design, pois seria difícil estender o Swing caso você tivesse que se preocupar com sincronização de threads.

ViniGodoy

Não entendi nada. Você pode explicar melhor? Bem perto do que? Que erro dá? O que você está tentando fazer?

Ah, e quando postar códigos, siga essas dicas:
http://www.guj.com.br/posts/list/50115.java

T

Deu certo aqui … só precisei ter mais calma e cabeça limpa, aí é só seguir o que falam

Muito obrigad viu

evertonsilvagomesjav

Quando você cria uma aplicação Swing, o Swing dispara uma segunda thread. Essa thread, faz todo o processamento da interface gráfica: lê eventos, pinta componentes, etc.

Toda a atualização de tela (abrir janelas, alterar text fields, labels, etc.) deve, obrigatoriamente, ser feito pela thread do Swing. É uma regra do Swing, pois ele não é thread-safe.

Mas, se vc estiver em outra thread, como fazer para atualizar um componente Swing? Os projetistas da API criaram então uma fila de eventos. A thread do Swing sempre lê nessa fila se há algo para fazer. E então executa o que estiver na fila.

Os comandos EventQueue.invokeLater e EventQueue.invokeAndWait são comandos thread-safe que permite inserir nessa fila um “pedido” ao Swing. Por exemplo, o pedido para abrir uma nova janela, ou para atualizar o componente. E como você diz a ele o que você quer? Colocando o código a ser executado dentro de um Runnable. Note que esse runnable não irá disparar uma nova thread. Trata-se só de um trecho de código para ser executável na thread do Swing, nada mais.

Sincronizar métodos não é a única forma de garantir thread-safety. Outra forma é não fazer com que threads interajam, e criar uma comunicação entre elas através de uma fila de mensagens. Essa abordagem, além de mais simples, simplifica o design, pois seria difícil estender o Swing caso você tivesse que se preocupar com sincronização de threads.

Eita não sabia que o Swing disparava um thread, achava que era tudo executado no “thread main”. Tipo nunca usei EventQueue.invokeLater(), por exemplo quando tenho um Frame e chamo um Dialog seria interessante nessa abordagem ao Dialog, usar invokeLater()?

Ou na hora de instanciar meu JFrame usa-lo?

ViniGodoy

evertonsilvagomesjava:
Eita não sabia que o Swing disparava um thread, achava que era tudo executado no “thread main”. Tipo nunca usei EventQueue.invokeLater(), por exemplo quando tenho um Frame e chamo um Dialog seria interessante nessa abordagem ao Dialog, usar invokeLater()?

Ou na hora de instanciar meu JFrame usa-lo?

Todos os eventos de botões já rodam dentro da thread do Swing.
Por isso, se você for abrir um JDialog a partir de um JFrame, você provavelmente fará isso através de um actionListener, que já está na thread certa, dispensando a chamada ao EventQueue.

É por isso também que se você colocar um processamento pesado num botão, você trava a interface gráfica. Como o processamento está na mesma thread que o Swing, nenhum pintura é refeita até que ele acabe. O normal é então criarmos uma segunda thread, ou um SwingWorker, para executar esse processamento. Porém, nesse caso, quando você for atualizar status (em labels, progressbars, etc), você precisará do EventQueue.

evertonsilvagomesjav

ViniGodoy:
evertonsilvagomesjava:
Eita não sabia que o Swing disparava um thread, achava que era tudo executado no “thread main”. Tipo nunca usei EventQueue.invokeLater(), por exemplo quando tenho um Frame e chamo um Dialog seria interessante nessa abordagem ao Dialog, usar invokeLater()?

Ou na hora de instanciar meu JFrame usa-lo?

Todos os eventos de botões já rodam dentro da thread do Swing.
Por isso, se você for abrir um JDialog a partir de um JFrame, você provavelmente fará isso através de um actionListener, que já está na thread certa, dispensando a chamada ao EventQueue.

É por isso também que se você colocar um processamento pesado num botão, você trata a interface gráfica. Como o processamento está na mesma thread que o Swing, nenhum pintura é refeita até que ele acabe. O normal é então criarmos uma segunda thread, ou um SwingWorker, para executar esse processamento. Porém, nesse caso, quando você for atualizar status (em labels, progressbars, etc), você precisará do EventQueue.

Humm, ta explicado porque quando eu uso um actionListener de um JButton pra fazer fazer uma consulta enorme no BD a interface trava kkk.

evertonsilvagomesjav

Vini tava pensando aqui sobre esse assunto, como toda a Interface do Swing roda numa Thread disparada pelo Swing, quando o netBeans faz aquela chamada no EventQueue é besteira entao nao é nao? Ele gera aquele codigo quando vai ser instanciado o Frame dentro do main, mas como o Frame ja vai rodar na thread do Swing, nao precisaria ele fazer isso pra colocar na fila de eventos para o Swing executar. Ta certo?

ViniGodoy

Não, pq sem aquilo, o construtor do JFrame e o comando setVisible() são disparados na main thread, e não na thread do Swing.

Não confunda. Não é o JFrame que roda dentro da thread do Swing.
É a thread do Swing que roda o código do JFrame.

Chamar o setVisible pela main thread vai fazer a main thread rodar por dentro do JFrame o que, pela arquitetura do Swing, é errado.

evertonsilvagomesjav

Não, pq sem aquilo, o construtor do JFrame e o comando setVisible() são disparados na main thread, e não na thread do Swing.

Não confunda. Não é o JFrame que roda dentro da thread do Swing.
É a thread do Swing que roda o código do JFrame.

Chamar o setVisible pela main thread vai fazer a main thread rodar por dentro do JFrame o que, pela arquitetura do Swing, é errado.

Entendi!! Vlw!!

D

No Netbeans 7.1 é muito fácil

Vc pode deixar qualquer objeto publico

Por exemplo:

Vc cria 2 JFrames no primeiro vc coloca um botão e no segundo vc coloca 2 JTextField
depois da um click no JTextField para selecioná-lo e nas propriedades vc clica em codigo, lá tem a opção Modificadores de variáveis com o valor private, mude o valor para public.
Pronto agora vc pode setar ele e mandar um valor os JTextField

No botão no Frame1 vc coloca.

NewJFrame2 frame2 = new NewJFrame2();   
      frame2.jTextField1.setText("aaaaaaaaaaaaa");
      frame2.jTextField2.setText("bbbbbbbbbbbbb");
      frame2.show();
Criado 3 de setembro de 2010
Ultima resposta 14 de ago. de 2012
Respostas 16
Participantes 4