StackOverflowError + KeyListener! Ajuda!

5 respostas
J

To querendo mover com o teclado um oval desenhado num Jpanel. Mas gera um erro muito extranho:

Exception in thread "main" java.lang.StackOverflowError
at sun.awt.windows.WToolkit.getScreenInsets(Native Method)
at sun.awt.windows.WToolkit.getScreenInsets(WToolkit.java:547)
at java.awt.Window.init(Window.java:394)
at java.awt.Window.(Window.java:432)
at java.awt.Frame.(Frame.java:403)
at java.awt.Frame.(Frame.java:368 )
at javax.swing.JFrame.(JFrame.java:163)
at TrandoEventosTec.(TrandoEventosTec.java:21)
at TrandoEventosTec.(TrandoEventosTec.java:26)

As classes:

import java.awt.event.KeyListener;  
import java.awt.event.KeyEvent;  
import javax.swing.JFrame;  
import javax.swing.JOptionPane; 
import java.awt.Graphics;

 	
 
 public class TrandoEventosTec extends JFrame implements KeyListener { 
 	
 	
 	public static void main(String[] args) {  
         TrandoEventosTec a = new TrandoEventosTec();
         	
     } 
 	
 	int x = 30;
 	Painel painel;
 	 
     public TrandoEventosTec() { 
     	 
         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         
         painel = new Painel();  
         TrandoEventosTec teclado = new TrandoEventosTec();
         
         teclado.add(painel);
         
            
         // ele é seu próprio escutador de eventos  
         addKeyListener(this);  

         setSize(640, 480);  
    
         setVisible(true);  
     }  
   
 
    
   
     public void keyPressed(KeyEvent ek){  
          
         if(ek.getKeyCode() == KeyEvent.VK_BACK_SPACE){
           
             painel.movaOval();} 
        
            
    }   
        
   
    
     public void keyTyped(KeyEvent ek) { }  
     public void keyReleased(KeyEvent ek) { }  
     	
    	
}

A que desenha:

import java.awt.Graphics;
import javax.swing.JPanel;

class Painel extends JPanel {
	 
	 int x = 20;
	 
	 public void paintComponent(Graphics g){
     	
     	super.paintComponent(g);
     	movaOval();
     	g.fillOval(x, x, 30, 30);
        //super.repaint(); 
     }
     
     void movaOval(){
     	x+=10;
     }
	
}

O que sei é que se eu tirar :

TrandoEventosTec teclado = new TrandoEventosTec();

teclado.add(painel);

por simplesmente:

this.add(painel);

Esse erro desaparece! Mas não sei se o que fiz é equivalente ao anterior!

Mas o que sei é que apesar do oval aparecer desenhado no Jpanel qnd clico no BACK_SPACE nada acontece!!!

Ajudem por favor!

5 Respostas

dreamspeaker

Eu não entendo quase nada de Swing, mas a exception dá pra entender da onde saiu.

Primeiro você precisa saber o que é um StackOverflowError:

Ou seja, você tem alguma coisa profudamente recursiva. E isso costuma acontecer quando vc dá um new classe dentro do construtor da classe. Porque ao executar o construtor ele dá um new, que vai chamar o construtor que vai dar um new, que vai chamar o construtor que vai dar um new… forever!

Abraço!

J
dreamspeaker:
jhooon:
...Exception in thread "main" java.lang.StackOverflowError
Eu não entendo quase nada de Swing, mas a exception dá pra entender da onde saiu.

Primeiro você precisa saber o que é um StackOverflowError:

"API do Java":
Thrown when a stack overflow occurs because an application recurses too deeply.

Ou seja, você tem alguma coisa profudamente recursiva. E isso costuma acontecer quando vc dá um new classe dentro do construtor da classe. Porque ao executar o construtor ele dá um new, que vai chamar o construtor que vai dar um new, que vai chamar o construtor que vai dar um new... forever!

Abraço!

Uhmmm! Mas já que é causado este erro dentro do construtor eu tirei os new de dentro do construtor e inicializei os objetos por fora! O erro persiste!

E outra coisa fora do comum! Criei uma classe Main donde coloquei meu metodo main e gera um novo erro NoSuchMethodError: main, tipo, como não acha o metodo main se ele ta explicito na classe Main!

Vou postar como ficou copila ai cara e ve se gera esse erro no seu pc! Pleaseee!

public class Main {

    	public static void main(String[] args) {  
         TrandoEventosTec a = new TrandoEventosTec();
         	
     }
    
    
}
import java.awt.event.KeyListener;  
import java.awt.event.KeyEvent;  
import javax.swing.JFrame;  
import javax.swing.JOptionPane; 
import java.awt.Graphics;

 	
 
 public class TrandoEventosTec extends JFrame implements KeyListener { 
 	
 	
  
 	
 	int x = 30;
 	Painel painel = new Painel();
 	TrandoEventosTec teclado = new TrandoEventosTec();
 	 
     public TrandoEventosTec() { 
     	 
         this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         
         
         
         teclado.add(painel);
         
            
         // ele é seu próprio escutador de eventos  
         addKeyListener(this);  

         setSize(640, 480);  
    
         setVisible(true);  
     }  
   
 
    
   
     public void keyPressed(KeyEvent ek){  
          
         if(ek.getKeyCode() == KeyEvent.VK_BACK_SPACE){
           
             painel.movaOval();} 
        
            
    }   
        
   
     // só para manter o compilador feliz  
     public void keyTyped(KeyEvent ek) { }  
     public void keyReleased(KeyEvent ek) { }  
     	
    	
}
import java.awt.Graphics;
import javax.swing.JPanel;

class Painel extends JPanel {
	 
	 int x = 20;
	 
	 public void paintComponent(Graphics g){
     	
     	super.paintComponent(g);
     	movaOval();
     	g.fillOval(x, x, 30, 30);
        super.repaint(); 
     }
     
     void movaOval(){
     	x+=10;
     }
	
}

[b]Será que existe a possibilidade de meu pc estar com problemas no hardware e gerar estes problemas?

abraços....

pmlm

TrandoEventosTec teclado = new TrandoEventosTec();

Exactamente o mesmo problema. Provavelmente deves querer tirar esta linha e usar this onde usas agora teclado.

J

pmlm:
TrandoEventosTec teclado = new TrandoEventosTec();

Exactamente o mesmo problema. Provavelmente deves querer tirar esta linha e usar this onde usas agora teclado.

Certo! Se eu faço isto o erro desaparece! O Jframe aparece na tela mas o oval que mandei ser printado na tela não aparece!!! Que devo fazer?

B

O erro acontece por que você está chamando o construtor do próprio objeto a partir de lugares que são parte da construção dele mesmo. Aí ele fica tentando se construir infinitamente.

Use o próprio objeto para tratar os eventos, no lugar de teclado coloque um this. Ficará this.add(painel);

Criado 19 de maio de 2009
Ultima resposta 20 de mai. de 2009
Respostas 5
Participantes 4