Thread X atualização de JFrame

Caros colegas, preciso de uma força…

Estou desenvolvendo um joguinho que quando o usuário clica em iniciar um JTextField mostra contagem regressiva de 10 segundos, em direção a 0…
À medida que o usuário vai acertando as respostas, o tempo é acrescido em 5 segundos… e assim vai até que ele perca…

só que o problema está que quando ele clica em iniciar, aparece uma nova janela, ao invés de a contagem iniciar na janela atual…

Eu retirei essa parte problemática do código, e coloco abaixo a parte correta do código para que vocês vejam a estrutura do JFrame…

E o que gostaria que vocês me ajudassem é a criar uma Thread para que a contagem do tempo não interfira no restante do o JFrame, e que quando essa Thread for iniciada ela faça o JFrame ficar tipo “dinâmico”, atualizando o tempo em tempo de execução.

Eis o código:


import java.awt.*;
import java.awt.event.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

public class Principal extends JFrame implements ActionListener {

    static JFrame janela = new Principal();

    JLabel loperacoes, lpontos, ltempo_restante, ldesafio,
           lacertos, lerros, ltotal_tempo, laproveitamento;
    JCheckBox cssoma, cssubtracao, csmultiplicacao, csdivisao;
    JComboBox cbnivel;
    JTextField tpontos, ttempo_restante, tvalor1, toperacao, tvalor2,
               ttotal, tacertos, terros, ttotal_tempo, taproveitamento;
    JButton biniciar, bsair;
    JTextArea taacertos, taerros, taorientacao;

    JPanel pesquerda ,peoperacoes, pedesafio, pepontos, pebotoes,
           pdireita, pdacertos_erros_geral, pdaeg_acertos, pdaeg_acertos_top,
           pdaeg_erros, pdaeg_erros_top,
           pdorientacao, pdcomplemento, pdcomplemento_tempo, pdcomplemento_aproveitamento;

    Principal(){

        setTitle("Desafios matemáticos");
        setSize(800,360);
        setLocation(0,0);
        getContentPane().setLayout(new GridLayout(1,2));

            //construção do painel da esquerda 2X2

            pesquerda = new JPanel();
            pesquerda.setLayout(new GridLayout(2,2));

                //construção do peoperacoes 6X1

                peoperacoes = new JPanel();
                peoperacoes.setLayout(new GridLayout(6,1));

                loperacoes = new JLabel("OPERAÇÕES");
                cssoma = new JCheckBox("soma");
                cssubtracao = new JCheckBox("subtração");
                csmultiplicacao = new JCheckBox("multiplicação");
                csdivisao = new JCheckBox("divisão");
                String []niveis={"fácil","médio","difícil"};
                cbnivel = new JComboBox(niveis);

                peoperacoes.add(loperacoes);
                peoperacoes.add(cssoma);
                peoperacoes.add(cssubtracao);
                peoperacoes.add(csmultiplicacao);
                peoperacoes.add(csdivisao);
                peoperacoes.add(cbnivel);

                //construção do pedesafio 5X1

                pedesafio = new JPanel();
                pedesafio.setLayout(new GridLayout(5,1));

                ldesafio = new JLabel("DESAFIO");
                tvalor1 = new JTextField();
                tvalor1.setEditable(false);
                toperacao = new JTextField("Operação: ");
                toperacao.setEditable(false);
                tvalor2 = new JTextField();
                tvalor2.setEditable(false);
                ttotal = new JTextField();

                pedesafio.add(ldesafio);
                pedesafio.add(tvalor1);
                pedesafio.add(toperacao);
                pedesafio.add(tvalor2);
                pedesafio.add(ttotal);

                //construção do pepontos 5X1

                pepontos = new JPanel();
                pepontos.setLayout(new GridLayout(4,1));

                lpontos = new JLabel("PONTOS");
                tpontos = new JTextField();
                tpontos.setEditable(false);
                ltempo_restante = new JLabel("TEMPO RESTANTE");
                ttempo_restante = new JTextField();
                ttempo_restante.setEditable(false);

                pepontos.add(lpontos);
                pepontos.add(tpontos);
                pepontos.add(ltempo_restante);
                pepontos.add(ttempo_restante);

                //construção do pebotoes north south

                pebotoes = new JPanel();
                pebotoes.setLayout(new GridLayout(2,1));

                biniciar = new JButton("INICIAR");
                biniciar.addActionListener(this);
                bsair = new JButton("SAIR");
                bsair.addActionListener(this);

                pebotoes.add(biniciar);
                pebotoes.add(bsair);

            pesquerda.add(peoperacoes);
            pesquerda.add(pedesafio);
            pesquerda.add(pepontos);
            pesquerda.add(pebotoes);

            //construção do pdireita

            pdireita = new JPanel();
            pdireita.setLayout(new GridLayout(3,1));

                //construção do painel geral da direita 1ª linha

                pdacertos_erros_geral = new JPanel();
                pdacertos_erros_geral.setLayout(new GridLayout(1,2));

                    //construção do painel acertos (geral)

                    pdaeg_acertos = new JPanel();
                    pdaeg_acertos.setLayout(new BorderLayout());

                        //construção do painel acertos top

                        pdaeg_acertos_top = new JPanel();
                        pdaeg_acertos_top.setLayout(new BorderLayout());

                        lacertos = new JLabel("ACERTOS");
                        tacertos = new JTextField();
                        tacertos.setEditable(false);

                        pdaeg_acertos_top.add("West",lacertos);
                        pdaeg_acertos_top.add("Center",tacertos);

                    taacertos = new JTextArea();
                    taacertos.setEditable(false);
                    taacertos.setBackground(Color.blue);
                    
                    pdaeg_acertos.add("North",pdaeg_acertos_top);
                    pdaeg_acertos.add("Center", taacertos);

                    //construção do painel erros (geral)

                    pdaeg_erros = new JPanel();
                    pdaeg_erros.setLayout(new BorderLayout());

                        //construção do painel erros top

                        pdaeg_erros_top = new JPanel();
                        pdaeg_erros_top.setLayout(new BorderLayout());

                        lerros = new JLabel("ERROS");
                        terros = new JTextField();
                        terros.setEditable(false);

                        pdaeg_erros_top.add("West",lerros);
                        pdaeg_erros_top.add("Center",terros);

                    taerros = new JTextArea();
                    taerros.setEditable(false);
                    taerros.setBackground(Color.red);

                    pdaeg_erros.add("North",pdaeg_erros_top);
                    pdaeg_erros.add("Center", taerros);


                pdacertos_erros_geral.add(pdaeg_acertos);
                pdacertos_erros_geral.add(pdaeg_erros);

                //construção do pdorientacao

                pdorientacao = new JPanel();
                pdorientacao.setLayout(new BorderLayout());

                taorientacao = new JTextArea();
                taorientacao.setEditable(false);
                taorientacao.setText("Escolha as operações desejadas,\n"+
                                     "depois o nível de dificuldade, e clique em iniciar!\n"+
                                     "na caixa de texto (<==), digite o valor que julgar responder ao desafio.\n"+
                                     "para corrigir, basta clicar \"enter\", estando com o cursor na caixa \n"+
                                     "de respostas. Nas caixas (azul e vermelha) serão listados erros e acertos.\n"+
                                     "Se o tempo restante chegar a zero, você perde.");

                pdorientacao.add("Center", taorientacao);

                //construção do pdcomplemento

                pdcomplemento = new JPanel();
                pdcomplemento.setLayout(new GridLayout(1,2));

                    //construção do pdcomplemtno_tempo

                    pdcomplemento_tempo = new JPanel();
                    pdcomplemento_tempo.setLayout(new BorderLayout());

                    ltotal_tempo = new JLabel("TOTAL DE TEMPO");
                    ttotal_tempo = new JTextField();
                    ttotal_tempo.setEditable(false);

                    pdcomplemento_tempo.add("North",ltotal_tempo);
                    pdcomplemento_tempo.add("Center",ttotal_tempo);


                    //construção do pdcomplemtno_aproveitamento

                    pdcomplemento_aproveitamento = new JPanel();
                    pdcomplemento_aproveitamento.setLayout(new BorderLayout());

                    laproveitamento = new JLabel("APROVEITAMENTO");
                    taproveitamento = new JTextField();
                    taproveitamento.setEditable(false);

                    pdcomplemento_aproveitamento.add("North",laproveitamento);
                    pdcomplemento_aproveitamento.add("Center",taproveitamento);


                pdcomplemento.add(pdcomplemento_tempo);
                pdcomplemento.add(pdcomplemento_aproveitamento);

            pdireita.add(pdacertos_erros_geral);
            pdireita.add(pdorientacao);
            pdireita.add(pdcomplemento);

        getContentPane().add(pesquerda);
        getContentPane().add(pdireita);
        setResizable(false);
    }

    public static void mostraJanela(){
        janela.repaint();
    }

    public void actionPerformed(ActionEvent e){

        if(e.getSource()==biniciar){


        }

    }

    public static void main(String args[]){

        janela.setUndecorated(true);
        janela.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
        janela.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        janela.setVisible(true);
    }

}

Eu ía fazer tudo pelo netbeans… só que o Layout depois começa a ficar ruim, então eu fiz essa estrutura de painéis que deixa qualquer um doido…rs…
Desde já agradeço!

(Para começar, devo afirmar que NÃO li seu código-fonte, portanto não posso comentá-lo. Mas vamos em frente…)

Para atualizar um componente Swing a partir de uma Thread em separado, você deve notificar o Swing de uma maneira bastante específica a partir da Thread em separado. Para isso, faça o seguinte na Thread em separado:

SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    componente.atualizar();
  }});