Então neste caso eu voltaria a usar o método sleep() da classe Thread, já que não usa mais a Timertask…
Isso aí roda o que tem no Runnable, uma única vez, daí a thread morre…
E sim, se vc quiser dar uma pausinha, é só usar o Thread.sleep.
class ProcessTask implements Runnable {
@Override
public void run() {
//Aqui chamamos o metodo através da EventQueue da AWT.
//Conforme dito, isso garante Thread safety para o Swing.
tc.IniciaProcesso();
EventQueue.invokeLater(new Runnable() {
public void run() {
//Atualize o swing com os resultados aqui.
}
});
}
}
Tá dando erro na linha da declaração do método run da ProcessTask (quote abaixo), na linha 3, se eu comento o ‘@Override’ aí ele para de dar erro, mas não faz sentido, o método a ser sobrescrito não é justamente o run()?
Segue abaixo a sua sugestão, Vini:[code] private void initComponents() throws InterruptedException
{
setTitle(“WebService Consulta”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jButton1 = new javax.swing.JButton();
jButton1.setText("Start");
jButton1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
new Thread(new ProcessTask()).start();
}
}
); [/code]Como faço pra dar o sleep na Thread, quando ela é declarada desta maneira com 'new'? Tentei da seguinte maneira, mas nao funcionou... :/ [code] private void initComponents() throws InterruptedException
{
setTitle("WebService Consulta");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jButton1 = new javax.swing.JButton();
jButton1.setText("Start");
jButton1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Thread t = new Thread(new ProcessTask()).start();
t.sleep(3600000);
}
}
); [/code]A Thread em questão vai saber que só é para ela dormir durante o tempo especificado depois que a tarefa no método chamado em Runnable for concluída? Ou vai dormir logo depois de realizar a chamada?
Declarar a Thread desta maneira está dando o seguinte erro:[quote]Type mismatch: cannot convert from void to Thread…[/quote]
Creio q assim não seja a melhor maneira…rs…mais uma vez obrigado.
O sleep faz a thread atual dormir.
Quem é a thread atual?
No método actionPerformed é a thread do Swing.
E no método run() é a nova thread, que você acabou de criar com o new.
Para fazer sua segunda thread dormir (e não a do botão), você deve mover o sleep para dentro do run, ou de qualquer método chamado pelo run.
Blz kra, it worked… 8) [code]class ProcessTask implements Runnable {
//@Override
public void run() {
//Aqui chamamos o metodo através da EventQueue da AWT.
//Conforme dito, isso garante Thread safety para o Swing.
tc.IniciaProcesso();
/*EventQueue.invokeLater(new Runnable() {
public void run() {
//Atualize o swing com os resultados aqui.
}
}); */
}
}
private void initComponents() throws InterruptedException
{
setTitle("WebService Consulta Indivíduos");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jButton1 = new javax.swing.JButton();
jButton1.setText("Start");
jButton1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
new Thread(new ProcessTask()).start();
}
}
);
…[/code]Reparou q eu comentei a EventQueue.invokeLater? E ainda assim funcionou…
O que exatamente eu teria necessidade de ‘invocar tardiamente’ ali?E o sleep eu coloquei dentro do método da outra classe:[code]public void IniciaProcesso()
{
try
{
ExportaConsultax ecx = new ExportaConsultax();
SimpleDateFormat sdf = new SimpleDateFormat(“dd/MM/yyyy - hh:mm:ss”);
SimpleDateFormat sdfLog = new SimpleDateFormat(“dd_MM_yyyy-hh.mm.ss”);
Thread t = new Thread();
t.start();
ecx.VerificaIndividuos(CICLO, CONTADOR);
Date d3 = new Date();
fc.createFile("C:\\", "ClienteInterfaceIndividuo_"+ sdfLog.format(d3) +".log", log.getLog());
log.setLog(null);
CICLO++;
CONTADOR = 1;
t.sleep(INTERVALO); //milisegundos
IniciaProcesso();
}
catch(Exception e)
{
e.printStackTrace();
}
} [/code]
Voltei um pouco á lógica inicial…o problema agora é q a JTextArea não está descendo com o scroll conforme vai acrescentando texto, mas aí já é outra história!!!
Preciso também criar um método para pausar esta thread, vou olhar nakele seu outro tópico.
VALEU Vini!
Você precisa chamar o invokeLater sempre que for atualizar um componente do Swing que não seja thread-safe. Não é o caso do JTextArea, mas é o caso da maioria: do JButton, JLabel, JTextField, e vários outros.
Geralmente, você só coloca os sets desses componentes dentro do InvokeLater, raramente um processamento.
Para movimentar o cursor do JTextArea é uma xunxeira desgraçada, por conta de uns bugs do próprio JTextPane.
Há uns tempos atrás postei aqui o código de um PrintWriter que escreve num JTextArea ou JTextPane, e já faz esse lance do cursor. Talvez você possa usa-lo. Ele também é thread-safe. O bom é que daí vc pode escrever no JTextArea com todos os métodos que vc teria usando o System.out, inclusive o printf.
Aqui está o link:
http://www.guj.com.br/posts/list/83462.java#445238
Eu geralmente uso com JTextPane para poder definir cores e formatação. Desenvolvemos um componente aqui baseado no Antlr que faz colorização automática dos nossos logs.
Brother não li as respostas pois estou com pressa, so li seu primeiro post…
Quanto a ficar travado, isso acontece pq o Swing tem prioridade diferentes em relação a seus componentes, por isso seu botão fica travado enquanto um Thread que foi chamada a partir da interface gráfica está rodando!
Faça o seguinte:
Thread threadProgress = new Thread(new Runnable() {
public void run() {
Controlador.diGrafu.getJProgressBar().setString("Executando...");
Controlador.diGrafu.getJProgressBar().setIndeterminate(true);
}
});
threadProgress.setDaemon(true);
threadProgress.start();
Thread threadDiGrafu = new Thread(new Runnable() {
public void run() {
ControlaExecucao.executaDiGrafu();
Controlador.diGrafu.getJProgressBar().setVisible(false);
}
});
threadDiGrafu .start();
Essas 2 Threads (threadProgress e threadDiGrafu ) uma controla um progressBar e a outra algumas execuções que eu faço.
Vc pode controlar seus botões na Thread threadProgress e as outras execuções que vc quer fazer na Thread threadDiGrafu
Se o seu problema é o que eu estou pensando com certeza vai dar certo…
flw
Foi mal people, andei enrolado com outras coisas (do mesmo sistema) e a interface acabou ficando por último…(prioridade é prioridade)
Mas não tem problema, o pesadelo voltou! rs…
Bom, como eu postei acima, consegui fazer a chamada do método que possui uma thread controladora de intervalos pelo JButton.
Eu clico no JButton e ele chama o método, esse método por sua vez inicia uma thread e esta thread controla intervalos de tempo neste método.
Agora criei um botão para pausar o funcionamento da thread, e adivinha: ele está ficando travado :roll:
[quote=Vini Godoy]Você precisa chamar o invokeLater sempre que for atualizar um componente do Swing que não seja thread-safe. Não é o caso do JTextArea, mas é o caso da maioria: do JButton, JLabel, JTextField, e vários outros.
Geralmente, você só coloca os sets desses componentes dentro do InvokeLater, raramente um processamento.
Para movimentar o cursor do JTextArea é uma xunxeira desgraçada, por conta de uns bugs do próprio JTextPane.
[/quote]
Creio que eu tenha que usar o InvokeLater neste JButton que invoca o Pause, concorda?
Eu fiz, mas nao adiantou…Vini, você disse atualizar…porém, creio que nao seria bem atualizar o JButton neste caso.
[code]Thread t = new Thread();
public void Pause() throws InterruptedException{
log.setPAUSE(true);
t.wait();
}
public void Resume() throws InterruptedException{
log.setPAUSE(false);
t.notify();
}
public void IniciaProcesso()
{
try
{
t.start();
ecx.VerificaIndividuos(CICLO, CONTADOR);
t.sleep(INTERVALO); //milisegundos
IniciaProcesso();
}
catch(Exception e)
{
e.printStackTrace();
}
}[/code]
Objetivo: se a pessoa clica no JButton ‘Start’ e deixa, o sistema executa a tarefa e depois de uma hora executa novamente, e assim fica eternamente.
Se alguém clicar no JButton ‘Pause’, ela tem que ficar parada até clicarem no Start novamente.
Acontece que quando invoco o método Pause pelo JButton ele trava o botão Pause, fica travado e a thread não pausa. :roll:
Resolvi colocar a Thread dentro da classe que usa o Swing, pois ficou mais simples e organizado.
(trecho):
private Thread t = new Thread();
public MainGui() {
initComponents();
}
class ProcessTask implements Runnable {
//@Override
public void run() {
//Aqui chamamos o metodo através da EventQueue da AWT.
//Conforme dito, isso garante Thread safety para o Swing.
new TarefaContinuax();
/*EventQueue.invokeLater(new Runnable() {
public void run() {
//Atualize o swing com os resultados aqui.
}
}); */
}
}
public ActionListener ActionStart = new ActionListener() {
public void actionPerformed(ActionEvent e) {
new Thread(new ProcessTask()).start();
}
};
ActionListener ActionPause = new ActionListener() {
public void actionPerformed(ActionEvent e) {
jTextArea1.append("\nProcesso interrompido...");
try{
t.wait();
}catch(InterruptedException ie){
jTextArea1.append("\nErro: "+ie.getMessage());
}
}
};
ActionListener ActionResume = new ActionListener() {
public void actionPerformed(ActionEvent e) {
jTextArea1.append("\nProcesso interrompido...");
t.notify();
}
};
A dúvida agora é como controlar a chamada de new TarefaContinua(); para acontecer de uma em uma hora, e os métodos para pausar e resumir a thread…
Agradeço qualquer ajuda pessoal.
[]´s