Estouro de pilhas

11 respostas
R

Estou tentando atualizar alguns campos na minha tela principal atraves de metodos de uma outra classe, essa classe vai ficar incrementando um valor e esse valor será mostrado num label na tela principal, tentei instanciar minha tela principal e executar um metodo que atualiza o campo, so que esta dando erro de estouro de pilha, tbm tentei usar o extends e executar diretamente o seu metodo, mas deu o mesmo erro

Alguem sabe como fazer essa atualização?

Vlw

11 Respostas

rapatao

Realmente não entendi muito bem o problema, mas posta a mensagem de erro, isso ajuda em uma possível solução!
Mas será que esse incremento não está estourando o tamanho suportado do tipo declarado?

R

Entaum car pior que naum é a soma que esta causando o erro, ja dei um system nessa variavel e o valor esta aparecendo certo, relamente é na hora de eu atualizar os dados no campo: o erro é esse:

<blockquote>Exception in thread “main” java.lang.StackOverflowError

at sun.awt.Win32GraphicsConfig.getBounds(Native Method)

at sun.awt.Win32GraphicsConfig.getBounds(Win32GraphicsConfig.java:240)</blockquote>

Imagine o seguinte tem uma classe que fica incrementando uma variavel o tempo todo, ao mesmo tempo ta rodando uma outra classe (tela principal) enquanto vai sendo mudado o valor da variavel de uma classe a outra tem que mudar ao mesmo tempo praticamente, to usando thread pra fazer isso.

vlw

rapatao

StackOverflowError, este é o problema!!
Tenta debugar seu código, ir num passo a passo mesmo…
Se ainda não conseguir, posta o código pra que eu possa tentar te ajudar melhor.

R

Então cara, esse erro ocorre assim que eu clico para iniciar o programa, naum consegui nem debuga ele, cliquei pra debugar e ja apareceu akele erro, é ao iniciar:

O codigo da minha classe filha é essa:
public class Cronometro extends principal implements Runnable{
    public String tempo = "";
    
    /** Creates a new instance of cronometro */
    public Cronometro(){
    }

    public void run() {        
        comece = true;
        
        inicio = System.currentTimeMillis();
        
        while(comece){ //se comece for true faça
            
            //.. conteudo
            
            //concatena
            tempo = String.valueOf(min) + ":" + String.valueOf(seg) + ":" + String.valueOf(cent);
            //return tempo;
            
            atualizaCronometro(tempo);
        }
        //return tempo;
    }
    public void stop(){
        comece = false;
    }
O metodo da classe principal é esse:
public void atualizaCronometro(String tempo){
        jtCronometroTP.setText(tempo);
    }

é isso cara, tem mais um monte de coisa mas o que eu uso mesmo pra atualizar meu campo é isso.

Vlw

rapatao

Aparentemente o problema não está neste seu código postado, mas me tire uma dúvida, por acaso você não faz uma chamada de uma nova instância da tela principal dentro da sua thread? Algo que faria com que seja iniciado uma nova tela inicial, que por sua vez cria uma nova thread contadora, enfim, nada parecido com isso?

R

Estou chamando aki:

private void jbCronometroTP1ActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: if(jbCronometroTP1.getText() == "Iniciar"){ jbCronometroTP1.setText("Parar"); new Thread(cr).start(); //System.out.println(cr.crono(true)); } else{ cr.stop(); jbCronometroTP1.setText("Iniciar"); //System.out.println(cr.crono(false)); } }

Vlw

rapatao

Fiz um exemplo pra você seguir como base, dê uma analisada no que fiz:

package principal;

import java.util.Date;

import javax.swing.JFrame;
import javax.swing.JTextField;

public class Principal {

	public static void main(String[] args) {
		Tela t = new Tela();
		t.setVisible(true);
	}

}

class Tela extends JFrame {

	private static final long serialVersionUID = 5519219173425709250L;
	private JTextField jTxt;

	public Tela() {
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setBounds(10, 10, 300, 300);
		this.add(getJTxt());
		new Thread(new Cronometro(this)).start();
	}

	public JTextField getJTxt() {
		if (this.jTxt == null) {
			this.jTxt = new JTextField();
		}
		return this.jTxt;
	}

	public void setJTxt(JTextField txt) {
		this.jTxt = txt;
	}

}

class Cronometro implements Runnable {

	private Tela principal;

	public Cronometro(Tela tela) {
		this.setPrincipal(tela);
	}

	public void run() {
		while (true) {
			getPrincipal().getJTxt().setText((new Date()).toString());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public Tela getPrincipal() {
		return principal;
	}

	public void setPrincipal(Tela principal) {
		this.principal = principal;
	}

}
R

Cara naum ta dando certo, esta aparecendo o mesmo erro de estouro de piha quando eu tento instanciar ou usar o extends, acrescentei os metodos que vc me passou na minha função mas ainda naum consegui atualizar o frame, a minha classe cronometor esta sem o sleep() tentei colocar mas naum fez diferença.
Vc conhece outro jeito pra fazer essa atrualização?

Vlw

rapatao

Acho que encontrei o problema, olhe seu código, em sua classe Cronometro você estende a classe Principal, quando você dá um new em Cronometro, você também está dando criando uma nova classe Cronometro, que por sua vez chama uma nova Principal e assim vai, por isso o StackOverFlow. Passe o objeto de principal na construção do Cronometro e use ele para alterar a tela e remova o extends Principal da classe Cronometro.

rapatao

Sobre o sleep()…
É que no meu caso, minha Thread não precisa ficar rodando continuamente e acredito que no seu também não, então este sleep() irá efetuar uma pausa na minha Thread, poupando assim o processador, enfim, faça os testes…

D

Só um detalhe, o Swing é single-threaded, e não há garantias de que atualizar componentes Swing em outras Threads não causem travamentos, erros inexplicáveis e congêneres.

A solução nesse caso seria algo como:

public void atualizaCronometro(String tempo){ SwingUtilities.invokeLater(new Runnable(){ public void run(){ jtCronometroTP.setText(tempo); } } }

Se preferir, poderia utilizar o invokeAndWait, que bloqueia a Thread atual até que a operação tenha terminado. Talvez seja o mais adequado.

T+

Criado 19 de outubro de 2007
Ultima resposta 21 de out. de 2007
Respostas 11
Participantes 3