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?
public class Time extends Thread {
public static void main(String[] args) {
String nome;
NomeRunnable nr = new NomeRunnable();
Thread a = new Thread(nr);
a.start();
nome = showInputDialog(null, "Informe seu nome", "Questão", JOptionPane.QUESTION_MESSAGE);
}
}
class NomeRunnable implements Runnable{
public void run() {
for (int i = 5; i >= 0; i--) {
System.out.println("Contagem: " + i);
try {Thread.sleep(1000);}
catch (InterruptedException iex) {}
}
showMessageDialog(null, "Tempo exedido","Mensagem", JOptionPane.INFORMATION_MESSAGE);
}
}
[quote=andeb]Funco aqui, mas não sei te dize até que ponto quebrei as boas práticas de programação Swing e Threads…
[code]
import java.util.concurrent.TimeUnit;
import javax.swing.JOptionPane;
public class RequestUserName implements Runnable {
private String name;
public static void main(String[] args) throws InterruptedException {
RequestUserName requestUserName = new RequestUserName();
Thread thread = new Thread(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());
}
}
@Override
public void run() {
name = JOptionPane.showInputDialog("Digite um nome:");
}
public String getName() {
return name;
}
}
[/code][/quote]
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.
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…
import java.util.concurrent.TimeUnit;
import javax.swing.JOptionPane;
public class RequestUserName implements Runnable {
private String name;
private Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
RequestUserName requestUserName = new RequestUserName();
final Thread thread = new Thread(requestUserName);
synchronized(requestUserName.lock) {
thread.start();
new ThreadExtension(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());
}
}
@Override
public void run() {
synchronized(lock) {
name = JOptionPane.showInputDialog("Digite um nome:");
lock.notifyAll();
}
}
public String getName() {
return name;
}
private static final class ThreadExtension extends Thread {
private final Thread thread;
private ThreadExtension(Thread thread) {
this.thread = thread;
setDaemon(true);
}
@Override
public void run() {
try {
TimeUnit.SECONDS.sleep(3);
if (thread.isAlive()) {
thread.interrupt();
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
[quote=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…
[/quote]
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.
package exercicio1;
import static javax.swing.JOptionPane.showInputDialog;
import static javax.swing.JOptionPane.showMessageDialog;
import javax.swing.JOptionPane;
public class LimiteTempo extends Thread implements Runnable{
private String nome;
/**
* Implementa método start para linha de execução secundária
*/
public void run() {
try{
for(int i = 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);
}
else if(this.getNome() != null){
showMessageDialog(null, ""+this.getNome()+". Seja bem vindo!", "Aviso", JOptionPane.INFORMATION_MESSAGE);
}
}catch(InterruptedException ie){
}
}
public void setNome(String nome){
this.nome = nome;
}
public String getNome(){
return this.nome;
}
/**
* Linha de execução primária
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException{
LimiteTempo lt = new LimiteTempo();
Thread a = new Thread(lt);
a.start();
lt.setNome(showInputDialog(null, "Informe seu nome", "Questão", JOptionPane.QUESTION_MESSAGE));
}
}