Problema com Foco

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?

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();
}