aos00
Dezembro 14, 2009, 12:48am
#1
ola pessoal!
Minha classe extende JFrame e possui um painel onde sao desehados quadrados continuamente e o frame atualizado com o repaint(). O frame possui tambem um menu. O problema eh que quando clico em um item do menu, o menu trava e apos isso, ele deixa de mostrar os quadrados sendo desenhados, nao responde com os comandos do teclado e nem consigo fechar o frame.
O que eu devo fazer para voltar a aparecer os quadrados sendo desenhados?
Fazendo um teste, eu mandei o jogo chamar o metodo de desenhar sem pecisar clicar no item do menu e ele desenhou sem problemas, mas se eu clicar em “play”, o ActionPerformed aciona o metodo iniciarJogo() e ele nao desenha nada nem responde aos comandos…
Percebi que quando o metodo iniciaJogo() eh executado, o isFocusOwner() retorna true.
public void actionPerformed(ActionEvent e) {
if (e.getSource() == playItem){
System.out.println(isFocusOwner()+"----"+desenha.isFocusOwner()+"---"+barra.isFocusOwner()+"---"+playItem.isFocusOwner()); //retorna false --- false ---false ---false
System.out.println("play");
playItem.setEnabled(false);
resetItem.setEnabled(true);
start = true;
requestFocus();
this.requestFocusInWindow();
iniciaJogo();
System.out.println(hasFocus()+"----"+desenha.isFocusOwner()+"---"+barra.isFocusOwner()+"---"+playItem.isFocusOwner()); //retorna false ---false ---false --false
As chamadas de repaint() são feitas a partir de onde?
aos00
Dezembro 14, 2009, 1:02pm
#3
O repaint eh chamado dentro do metodo iniciaJogo(). Esse metodo possiu um while e, dentro dele, um for. O repaint() esta dentro do for.
public void iniciaJogo(){
while(start == true){
numeroDeJogadas += 1;
ptos = Integer.toString(pontos);
pontuacaoItem.setText(ptos);
x=10;
speed = 200 - 2*numeroDeJogadas;
peca = peca.getPeca();
for(int y=(grid.getAltura()-peca.getAltura());y>=-1;y--){
retorno = grid.colocaPeca(peca, x, y);
try{
Thread.sleep(speed);
}catch(Exception ex){
System.out.println("exception do thread!!");
}
System.out.println(hasFocus()+"----"+desenha.isFocusOwner()+"---"+barra.isFocusOwner()+"---"+playItem.isFocusOwner());
System.out.println("Posicao:("+x+","+y+")----retorno: "+retorno+"-----velocidade:"+speed);
switch(retorno){
case 0:
repaint(); // REPAINT()
grid.undo(memento);
yValido = y;
xValido = x;
break;
case 1:
grid.apagarLinhas();
grid.commitEstado();
grid.salvaEstado(memento);
pontos += 100;
break;
case 2:
grid.undo(memento);
grid.colocaPeca(peca, xValido, yValido);
repaint();
grid.commitEstado();
grid.salvaEstado(memento);
break;
case 3:
if((y==grid.getAltura()-peca.getAltura())){
start=false;
System.out.println("vc perdeu");
y = -2; //flag para sair do for
break;
}else{
grid.undo(memento);
grid.colocaPeca(peca, xValido, yValido);
grid.commitEstado();
grid.salvaEstado(memento);
y = -2; // flag para sair do for
break;
}
}
}
}
}
Não vai dar certo assim. Quando as chamadas de repaint() são feitas na mesma Thread do Swing, as coisas não funcionam.
O certo seria colocar todo o conteúdo desse método em uma Thread separada. O meio mais fácil de se fazer isso é assim:
public void iniciaJogo() {
new Thread() {
public void run() {
// todo o código que estava dentro de iniciaJogo() fica aqui
}
}.start();
}