Estou tentando resolver um problema utilizando Threads porém estou “batendo cabeça” em algo que seja simples. Preciso criar uma pequena aplicação, está aplicação exibe um JOptionPane exigindo uma informação do usuário. Se o usuário não digitar nada nestes 10 segundos, o OptionPane é fechado. Minhas dúvidas são:
O meu JOptionPane deve ficar na classe que implementa Runnable(Ex abaixo) aonde minhas threads são iniciadas, ou ficar na app principal?
Quando termina os 10 segundos da thread, como consigo identificar isso e dizer para neu OptionPane fechar?
publicclassTimeextendsThread{publicstaticvoidmain(String[]args){Stringnome;NomeRunnablenr=newNomeRunnable();Threada=newThread(nr);a.start();nome=showInputDialog(null,"Informe seu nome","Questão",JOptionPane.QUESTION_MESSAGE);}}classNomeRunnableimplementsRunnable{publicvoidrun(){for(inti=5;i>=0;i--){System.out.println("Contagem: "+i);try{Thread.sleep(1000);}catch(InterruptedExceptioniex){}}showMessageDialog(null,"Tempo exedido","Mensagem",JOptionPane.INFORMATION_MESSAGE);}}
Funco aqui, mas não sei te dize até que ponto quebrei as boas práticas de programação Swing e Threads…
importjava.util.concurrent.TimeUnit;importjavax.swing.JOptionPane;publicclassRequestUserNameimplementsRunnable{privateStringname;publicstaticvoidmain(String[]args)throwsInterruptedException{RequestUserNamerequestUserName=newRequestUserName();Threadthread=newThread(requestUserName);thread.start();TimeUnit.SECONDS.sleep(3);if(requestUserName.getName()==null){thread.interrupt();JOptionPane.showMessageDialog(null,"Tempo excedido");}else{JOptionPane.showMessageDialog(null,"Nome Escolhido foi: "+requestUserName.getName());}}@Overridepublicvoidrun(){name=JOptionPane.showInputDialog("Digite um nome:");}publicStringgetName(){returnname;}}
augustocolom
andeb:
Funco aqui, mas não sei te dize até que ponto quebrei as boas práticas de programação Swing e Threads...
importjava.util.concurrent.TimeUnit;importjavax.swing.JOptionPane;publicclassRequestUserNameimplementsRunnable{privateStringname;publicstaticvoidmain(String[]args)throwsInterruptedException{RequestUserNamerequestUserName=newRequestUserName();Threadthread=newThread(requestUserName);thread.start();TimeUnit.SECONDS.sleep(3);if(requestUserName.getName()==null){thread.interrupt();JOptionPane.showMessageDialog(null,"Tempo excedido");}else{JOptionPane.showMessageDialog(null,"Nome Escolhido foi: "+requestUserName.getName());}}@Overridepublicvoidrun(){name=JOptionPane.showInputDialog("Digite um nome:");}publicStringgetName(){returnname;}}
Olá andeb,
Entendi, realmente desta forma ele funciona, mas o problema é que mesmo quando o usuário informa o nome ele é forçado a esperar pelo tempo estipulado, aí fico no mesmo problema.
andeb
Ah sim, perfeito, falha minha hehe
Assim funciona agora, tem um monitor para notificar que foi setado o valor e notificar a outra thread que ela pode prosseguir e uma outra thread para matar a thread que pede o nome do usuário, minha ideia a principio era só ter usado o objeto monitor, mas depois de que o wait(3*1000) termina, a thread main não volta para o código do main(String…), não entendi o porque…
importjava.util.concurrent.TimeUnit;importjavax.swing.JOptionPane;publicclassRequestUserNameimplementsRunnable{privateStringname;privateObjectlock=newObject();publicstaticvoidmain(String[]args)throwsInterruptedException{RequestUserNamerequestUserName=newRequestUserName();finalThreadthread=newThread(requestUserName);synchronized(requestUserName.lock){thread.start();newThreadExtension(thread).start();requestUserName.lock.wait(3*1000);}if(requestUserName.getName()==null){thread.interrupt();JOptionPane.showMessageDialog(null,"Tempo excedido");}else{JOptionPane.showMessageDialog(null,"Nome Escolhido foi: "+requestUserName.getName());}}@Overridepublicvoidrun(){synchronized(lock){name=JOptionPane.showInputDialog("Digite um nome:");lock.notifyAll();}}publicStringgetName(){returnname;}privatestaticfinalclassThreadExtensionextendsThread{privatefinalThreadthread;privateThreadExtension(Threadthread){this.thread=thread;setDaemon(true);}@Overridepublicvoidrun(){try{TimeUnit.SECONDS.sleep(3);if(thread.isAlive()){thread.interrupt();}}catch(InterruptedExceptione){thrownewRuntimeException(e);}}}}
augustocolom
andeb:
Ah sim, perfeito, falha minha hehe
Assim funciona agora, tem um monitor para notificar que foi setado o valor e notificar a outra thread que ela pode prosseguir e uma outra thread para matar a thread que pede o nome do usuário, minha ideia a principio era só ter usado o objeto monitor, mas depois de que o wait(3*1000) termina, a thread main não volta para o código do main(String…), não entendi o porque…
Consegui resolver, fiz baseado em uma linha de execução secundária mesmo. Já que Threads não te apresenta muita segurança na execução linear dos códigos, acredito que resolva meu problema. Mas obrigado pela ajuda, esclareceu bastante o exemplo de cima.
packageexercicio1;import staticjavax.swing.JOptionPane.showInputDialog;import staticjavax.swing.JOptionPane.showMessageDialog;importjavax.swing.JOptionPane;publicclassLimiteTempoextendsThreadimplementsRunnable{privateStringnome;/** * Implementa método start para linha de execução secundária */publicvoidrun(){try{for(inti=10;i>-1;i--){if(this.getNome()!=null)break;sleep(1000);}if(this.getNome()==null){showMessageDialog(null,"Tempo exedido","Aviso",JOptionPane.INFORMATION_MESSAGE);System.exit(0);}elseif(this.getNome()!=null){showMessageDialog(null,""+this.getNome()+". Seja bem vindo!","Aviso",JOptionPane.INFORMATION_MESSAGE);}}catch(InterruptedExceptionie){}}publicvoidsetNome(Stringnome){this.nome=nome;}publicStringgetNome(){returnthis.nome;}/** * Linha de execução primária * @param args * @throws InterruptedException */publicstaticvoidmain(String[]args)throwsInterruptedException{LimiteTempolt=newLimiteTempo();Threada=newThread(lt);a.start();lt.setNome(showInputDialog(null,"Informe seu nome","Questão",JOptionPane.QUESTION_MESSAGE));}}