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

{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 !!!

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

Nesse tem um exemplo funcionando.

[quote=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 !!![/quote]

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

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

Dentro da class TelaDois

[code]String minhaString;

public TelaDois(String minhaStringViajante){

this.minhaString = minhaStringViajante;

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

}[/code]

Desculpa Vini, não vi vc respondendo.

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

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.

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

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.

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

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

Muito obrigad viu

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.[/quote]

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?

[quote=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?[/quote]

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.

[quote=ViniGodoy][quote=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?[/quote]

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.[/quote]

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

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?

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.

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.[/quote]

Entendi!! Vlw!!

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();