entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

¿Bucle While no funciona?

Buenas tardes compañeros, estoy intentando hacer un contador pero por alguna razón me da null...

package AutoClick;

import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import java.awt.Point;

@SuppressWarnings("serial")
public class TiempoSleep extends JFrame {
    AutoClick AC = new AutoClick();
    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TiempoSleep frame = new TiempoSleep();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public TiempoSleep() {
        setLocation(new Point(200, 200));
        setLocationRelativeTo(null);
        setResizable(false);
        byte tiempo = 5;

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 212, 164);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JLabel Sleep = new JLabel();
        Sleep.setFocusable(false);
        Sleep.setBounds(58, 11, 81, 54);
        contentPane.add(Sleep);

        JLabel lblPosicioneElPuntero = new JLabel("Posicione el puntero de su rat\u00F3n");
        lblPosicioneElPuntero.setBounds(10, 76, 191, 14);
        contentPane.add(lblPosicioneElPuntero);
        String sleepTime = Integer.toString(tiempo);
        while (tiempo > 0){
            tiempo-=1;
            Sleep.setText(sleepTime);
            if (tiempo == 0){
                System.out.println("Time!");
                /*try {
                    AC.Timer3();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }*/
            }
        }
    }
}

Por alguna razón, no se actualiza nunca el JLabel con el resutado del while...pero el caso es que llega al Time! que le tengo puesto en imprimir pantalla...

0voto

Yesod comentado

He dado con el error, pero no se como "solucionarlo", el problema que solo se muestra el resultado final en el JTextField, no todo el bucle como pretendo, es decir, que en el JTextField se muestre: 5,4,3,2,1,0...

2 Respuestas

2votos

Leonardo-Tadei Puntos227320

Hola,

para mostrar los valores acumulados, usá una variable string para ir concatenando el resultado del bucle en cada iteración, y luego mostrá el valor de esta variable.

Cada asignación del tiempo al JTextField te pondrá ese valor, no la acumulación de los resultados.

Esto mostrará los resultados todos juntos al final. Si querés ver los resultados a medida que el bucle se ejecuta, tenés que refrescar el componente luego de la asignación.

Saludos!

0voto

Yesod comentado

Estoy intentando hacer un timer, realmente tengo ni idea de como conseguir este efecto, pero ya el propio timer me esta dando problemas (para construirlo)

Me han comentado por otro lado que haga un hilo...pero, con la palabra Thread como tal, no sale opción o si hago una clase para que me haga el trabajo y me devuelva todo el rato, me hace lo mismo que si lo pongo todo en la misma clase.

0voto

Leonardo-Tadei comentado

Es que Java, salvo que digas lo contrario, corre todo en un solo hilo de ejecución, con lo que el programa se queda esperando hasta que termina el bucle para continuar, con lo que por ejemplo es inviable por ejemplo mostrar un reloj en tu aplicación y usarla al mismo tiempo.

Tal vez te sirva este ejemplo (está en inglés, pero es fácil de leer) que habla sobre el tema y sobre cómo se implementa un timer: http://www.journaldev.com/1050/java-timer-and-timertask-example-tutorial

Saludos!

0voto

Yesod comentado

He implementado lo siguiente:

// Declaramos un timer que nos actualice el JTextField cada segundo
    Timer CountDown = new Timer(1000, new ActionListener() {
        // Declaramos el método para la cuenta atrás
        public void actionPerformed(ActionEvent e) {
            try {
                //Tiempo para crónometro
                Sleep.setText(cronometro.SleepTime(segundos));
                String tiempo = Sleep.getText();
                if (tiempo.equals("0")){
                    System.out.println("Tiempo");
                    CountDown.stop();
                }
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    });

Ahora me muestra tanto el JFrame como el resultado final, pero no la secuencia y bueno, actúa como bucle infinito...

0voto

Leonardo-Tadei comentado

Hola Yesod,

mejor controlá el tiempo con un integer en vez de con un string, y salí del bucle si el valor es <= 0.

Tu bucle no termina nunca salvo que, de casualidad, pase exactamente por el valor 0 en el momento de la evaluación... supongo que implementaste esto en una nueva tarea, y por tanto, dependés de la velocidad de la comunicación entre ellas para atender a los eventos.

Saludos!

0voto

Yesod comentado

Tengo el siguiente código, a ver si me puedes echar un cable y solucionarmelo plz:

Esto esta en la clase del JFrame

// Declaramos un timer que nos actualice el JTextField cada segundo
Timer CountDown = new Timer(1000, new ActionListener() {
    // Declaramos el método para la cuenta atrás
    public void actionPerformed(ActionEvent e) {
        try {
            // Tiempo para crónometro
            tiempo = Integer.toString(cronometro.SleepTime(segundos));
            Sleep.setText(tiempo);
            if (cronometro.SleepTime(segundos)==0){
                System.out.println("Tiempo");
                CountDown.stop();
            }
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
    }
});

Y esto, esta en la clase "cronometro" que es la que se encarga de varias cuenta atrás en el mismo programa.

public static int SleepTime(int segundos) throws InterruptedException{
    while (segundos>0){
        try {
            Thread.sleep(1000);
            segundos-=1;
        }finally{}
    }
    return segundos;

0voto

Leonardo-Tadei comentado

Y de dónde toma el valor y lo cambia la variable segundos fuera del método SleepTime()???

Queda claro qué es lo que hace el método SleepTime() pero no veo dónde usás el valor devuelto, que es la variable de control del bucle...

0voto

Yesod comentado

No entiendo a que te refieres, ¿No se supone que yo al poner "return segundos" estoy devolviendo en resultado que tomar "segundos" en cada vuelta?

0voto

Leonardo-Tadei comentado

Hola Yesod,

tal y como decís, al poner en el método return segundos estás devolviendo el valor de los segundos en el método SleepTime() pero lo que hace el método, es una pausa y restar 1 al valor pasado como parámetro, así que el control del bucle (la variable de control) depende de que mantengas fuera del método el valor de los segundos, porque si no, nunca llegará a cero.

Si hacés por ejemplo:

SleepTime(10)

Entrás al método con valor 10, se ejecuta y devuelve 9... pero ahora tenés que pasarle el neuvo valor, que es 9, porque si lo volvés a llamar con SleepTime(10), por más que lo llames mil veces, siempre devolverá 9 y nunca se dejará de ejecutar...

0voto

Yesod comentado

He implementado lo que me has dicho, pero ahora, me he perdido en mi propio código (cosas que pasa por no comentar), ahora mismo no se en que momento le paso la variable segundos a la clase cronómetro...

// Declaramos un timer que nos actualice el JTextField cada segundo
    Timer CountDown = new Timer(1000, new ActionListener() {
        // Declaramos el método para la cuenta atrás
        public void actionPerformed(ActionEvent e) {
            try {
                // Tiempo para crónometro
                tiempo = Integer.toString(cronometro.SleepTime(segundos));
                Sleep.setText(tiempo);
                if (cronometro.SleepTime(segundos)==0){
                    System.out.println("Tiempo");
                    CountDown.stop();
                }
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    });
}

Y luego, he implentado lo que me dijiste:

public static int SleepTime(int segundos) throws InterruptedException{
    int secaux = segundos;
    while (secaux>0){
        try {
            Thread.sleep(1000);
            secaux-=1;
        }finally{}
    }
    return secaux;
}

0voto

Leonardo-Tadei comentado

Es que creo que no encontrás en dónde le pasás el valor a la clase Cronómetro, porque la estás llamando con un valor sin inicializar...

Por otra parte, el código nuevo de SleepTime() no resuelve tu probleme, ya que el valor de secaux (o el de segundos en la versión anterior) como es local el método, no queda guardado para la próxima iteración: tenés que mantener una varialbe fuera del método con el valor para que esto funcione!

0voto

Yesod comentado

Realmente creo que si se lo paso, he estado revisando el código porque me hice un lío.

package AutoClick;

import java.awt.EventQueue;
import java.awt.Font;

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

import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

@SuppressWarnings("serial")
public class TiempoSleep extends JFrame {
    AutoClick AC = new AutoClick();
    private JLabel PosicioneElPuntero;
    private JTextField Sleep;
    public int segundos = 5;
    String tiempo;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TiempoSleep frame = new TiempoSleep();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public TiempoSleep() throws InterruptedException {
        initcomponents();
        CountDown.start();
    }

    public void initcomponents() throws InterruptedException {
        // Propiedades del JFrame
        setLocation(new Point(200, 200));
        setLocationRelativeTo(null);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 212, 164);
        getContentPane().setLayout(null);

        Sleep = new JTextField();
        Sleep.setEditable(false);
        Sleep.setEnabled(false);
        Sleep.setFocusable(false);
        Sleep.setBorder(null);
        Sleep.setFont(new Font("Tahoma", Font.BOLD, 30));
        Sleep.setBounds(84, 11, 112, 54);
        getContentPane().add(Sleep);

        PosicioneElPuntero = new JLabel("Posicione el puntero de su rat\u00F3n");
        PosicioneElPuntero.setBounds(10, 76, 191, 14);
        getContentPane().add(PosicioneElPuntero);
    }
    // Declaramos un timer que nos actualice el JTextField cada segundo
    Timer CountDown = new Timer(1000, new ActionListener() {
        // Declaramos el método para la cuenta atrás
        public void actionPerformed(ActionEvent e) {
            try {
                // Tiempo para crónometro
                tiempo = Integer.toString(cronometro.SleepTime(segundos));
                Sleep.setText(tiempo);
                if (cronometro.SleepTime(segundos)==0){
                    System.out.println("Tiempo");
                    CountDown.stop();
                }
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    });
}

La variable segundos, la tengo inicializada en 5, y se la paso cuando hago: tiempo = Integer.toString(cronometro.SleepTime(segundos)); que a su vez (creo), que transformo en String para poder mostrarlo en pantalla...

La otra parte realmente (creo), que, cuando yo le paso el valor de segundos y lo guardo en secaux, ya se debería quedar guardada en esa variable, que es la que uso para hacer el contador, ¿no?

Creo que puedes verme que me estoy liando bastante, debería ser mas sencillo...y me estoy haciendo un lío demasiado gordo.

0voto

Leonardo-Tadei comentado

Hola yesod,

ese es justamente el error de concepto que te estaba indicando!

Estás inicializando segundos = 5 y llamás a tu clase con tiempo = Integer.toString(cronometro.SleepTime(segundos));

Tu implementación de SleepTime() pone a la variable de control afuera del método, por lo que si no volvés a asignar a la variable segundos el valor devuelto por SleepTime() nunca va a recibir un valor distinto de 5!!! El atributo público segundos nunca toma un nuevo valor.

Tenés que hacer algo como:

...
this.segundos = cronometro.SleepTime(this.segundos);
tiempo = Integer.toString(this.segundos);
...

o alternativamente usar this.segundos dentro de SleepTime() para que le vaya cambiando el valor.

0voto

Yesod comentado

Vale, entonces, ahora tengo esto:

package AutoClick;

import java.awt.EventQueue;
import java.awt.Font;

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

import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

@SuppressWarnings("serial")
public class TiempoSleep extends JFrame {
    AutoClick AC = new AutoClick();
    private JLabel PosicioneElPuntero;
    private JTextField Sleep;
    public int segundos = 5;
    String tiempo;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TiempoSleep frame = new TiempoSleep();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public TiempoSleep() throws InterruptedException {
        initcomponents();
        CountDown.start();
    }

    public void initcomponents() throws InterruptedException {
        // Propiedades del JFrame
        setLocation(new Point(200, 200));
        setLocationRelativeTo(null);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 212, 164);
        getContentPane().setLayout(null);

        Sleep = new JTextField();
        Sleep.setEditable(false);
        Sleep.setEnabled(false);
        Sleep.setFocusable(false);
        Sleep.setBorder(null);
        Sleep.setFont(new Font("Tahoma", Font.BOLD, 30));
        Sleep.setBounds(84, 11, 112, 54);
        getContentPane().add(Sleep);

        PosicioneElPuntero = new JLabel("Posicione el puntero de su rat\u00F3n");
        PosicioneElPuntero.setBounds(10, 76, 191, 14);
        getContentPane().add(PosicioneElPuntero);
    }

    public TiempoSleep(int segundos) throws InterruptedException {
        this.segundos = cronometro.SleepTime(this.segundos);
        tiempo = Integer.toString(this.segundos);
    }

    // Declaramos un timer que nos actualice el JTextField cada segundo
    Timer CountDown = new Timer(1000, new ActionListener() {
        // Declaramos el método para la cuenta atrás
        public void actionPerformed(ActionEvent e) {
            // Tiempo para crónometro
            try {
                // Paso el parámetro segundos al método "SleepTime" dentro de la clase "Cronómetro"
                // Luego lo paso a String para poder utilizarlo en el JTextField
                tiempo = Integer.toString(cronometro.SleepTime(segundos));
                Sleep.setText(tiempo);
                if (cronometro.SleepTime(segundos)==0){
                    System.out.println("Tiempo");
                    CountDown.stop();
                }
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    });
}

He implementado lo que me has dicho, pero sigue sin funcionar...también he probado a poner el valor de la variable sexaux como variable glogal y, el tema es que me sigue haciendo lo mismo, solo me saca el valor cuando llega a 0.

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package AutoClick;

/**
 *
 * @author Jorge Félix
 */
public class cronometro {
    static int secaux;
    public static String cronometroT(int segundos){
        int minutos=0;
        int horas=0;
        while (segundos>59){
            segundos-=60;
            minutos++;
            if (minutos>59){
                minutos-=60;
                horas++;
                }
        }
        return (horas+":"+minutos+":"+segundos);
    }
    public static int SleepTime(int segundos) throws InterruptedException{
        secaux = segundos;
        while (secaux>0){
            try {
                Thread.sleep(1000);
                secaux-=1;
            }finally{}
        }
        return secaux;
    }
}

Me han dicho que también puedo usar un switch o varios else if (algunos programadores amigos mios), pero no quiero hacerlo tan guarro...

La salida que me da es la siguiente:

TIempo después4
TIempo después3
TIempo después2
TIempo después1
TIempo después0
TIempo después4
TIempo después3
TIempo después2
TIempo después1
TIempo después0
Tiempo

Gracias por todo amigo :D

PD: Te agradecería si me puedes poner la solución directa a este problema :D


EDITO: Lo he planteado de otra forma y funciona, pero el caso es que no se como cerrar el hilo desde la clase principal, tengo hecho esto:

public void quitarAlways(boolean valor){
        this.setAlwaysOnTop(valor);
    }
public void Button_EjecutarActionPerformed(java.awt.event.ActionEvent evt) throws InterruptedException {
    quitarAlways(false);
    Hilo.start();
}

Con esto Inicio el Hilo para el contador, pero el problema es que... a la hora de hacer esto:

   public void Timer3() throws InterruptedException {
       try {
           timer2.start();
           quitarAlways(true);
       } finally {}
    }

Si pongo, Hilo.close(); me sale como deprecated...y no tengo ni idea de como cerrar el Hilo entonces.

En el Hilo tengo esto:

package AutoClick;

import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;

@SuppressWarnings("serial")
public class Contador extends JFrame implements Runnable, ActionListener {
    AutoClick AC = new AutoClick();

    static int t=6;
    private JLabel PosicioneElPuntero;
    private JLabel c;
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        /*Contador c = new Contador();
        Thread Hilo = new Thread(c);
        Hilo.start();*/
    }
    /**
     * Create the frame.
     */
    public Contador() {
        this.objs();
        // Propiedades del JFrame
        this.setTitle("Contador");
        this.setLocation(new Point(580, 280));
        this.setSize(new Dimension(209,110));
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
    }

    public void objs() {
        getContentPane().setLayout(null);

        c = new JLabel(""+t);
        c.setBounds(100,11,60,20);
        getContentPane().add(c);

        PosicioneElPuntero = new JLabel("Posicione el puntero de su rat\u00F3n");
        PosicioneElPuntero.setBounds(10, 42, 191, 14);
        getContentPane().add(PosicioneElPuntero);
    }

    public void run (){
        try {
            while (true){
                t-=1;
                c.setText(""+t);
                Thread.sleep(1000);
                if (t==1){
                    AC.Timer3();
                }
            }
        }catch (Exception e){}
    }
    public void actionPerformed(ActionEvent arg0) {

    }
}

¿Que se os ocurre?

0voto

Leonardo-Tadei comentado

"Gracias por todo amigo :D
PD: Te agradecería si me puedes poner la solución directa a este problema :D"

Sería un muy mal amigo si te escribiese la solución: un buen amigo te ayudaría a entender qué es lo que pasa para que aprendas a resolver estas cuestiones para siempre.

Si querés usar una solución que funciona sin entenderla, usá la de @xabe que está muy bien pensada, pero de una forma muy distinta a como estás queriendo solucionar este problema.

Saludos cordiales!

PD: te sugiero plantear la cuestión de cómo cerrar el thread en una pregunta aparte y de ser posible con un título más descriptivo que esta, ya que tu problema poco tenía que ver con un bucle while.

0voto

xabe comentado

Hola

Como bien dice @Leonardo-Tadei tendria que darte una explicación de mi código no solo dartelo y no explicar porque lo hecho así, Cuando arrancamos una aplicación de escritorio java tenemos un hilo principal (en realidad hay másde uno pero para nosotros es como si fuera uno) que es el encargado crear nuestra interfaz y de escuchar los eventos que se produce en ella y notificar esos eventos a nuestra clase java que implementan la interfaz ActionListener. En nuestro caso queremos mostrar un contador en nuestra aplicación, para realizar esta tarea, tenemos que hacer alguien cada cierto tiempo va cambiando el valor de nuestro contador. Ese alguien va ser un thread que cada segundo va actualizar el valor de nuestro contador. Los thread nos puede ayudar en un montón de casos pero tambien nos puede dar mucho dolor de cabeza (multi hilos, concurrencia, etc..).

Como vien sabe el método principal de thread es "run" hay donde tenemos que implemetar toda nuestra lógica.
En la mayoría de los casos queremos tener control sobre el hilo de cuando arrancar, parar y pausar. Para eso tengo una clase base de un thread que es la siguiente:

public class MyThread implements Runnable {

    private volatile boolean isRunning = true;
    private volatile boolean isPausing = false;

    public void run() {
        while (isRunning && !Thread.currentThread().isInterrupted() ) {
            if(!isPausing)
            {
                //Done
            }
        }
    }

    public void kill() {
        isRunning = false;
    }

    public void pause() {
        isPausing = true;
    }

    public void resume() {
        isPausing = false;
    }
}

Como ves tenemos los metodos para para y pausar el hilo. Para nuestro problema seria implemetar la logia de actulizar la etiqueta cada segundo seria algo parecido a esto.

public class ContadorThread implements Runnable {

    private volatile boolean isRunning = true;
    private int tiempo;
    private final JLabel etiqueta;

    public ContadorThread(JLabel etiqueta, int tiempo) {
        this.tiempo = tiempo;
        this.etiqueta = etiqueta;
    }

    public void run() {
        while (isRunning && !Thread.currentThread().isInterrupted() ) {
            try
            {
                tiempo -= 1;
                etiqueta.setText("" + tiempo);
                Thread.sleep(1000);
                if (tiempo==1)
                {
                    kill();
                }
            }catch(Exception e){}
        }
        System.out.println("Termina el Hilo");
    }

    public void kill() {
        isRunning = false;
    }
}

Ahora solo falta el codigo de nuestra clase principal donde va crear la clase ContadorThread y arrancar nuestro hilo.

@SuppressWarnings("serial")
public class Contador extends JFrame implements ActionListener {

    private JLabel PosicioneElPuntero;
    private JLabel c;
    private ContadorThread contadorThread;
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        new Contador();
    }
    /**
     * Create the frame.
     */
    public Contador() {
        this.objs();

        // Propiedades del JFrame
        this.setTitle("Contador");
        this.setLocation(new Point(580, 280));
        this.setSize(new Dimension(209,110));
        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        Thread thread = new Thread(contadorThread);
        thread.start();
    }

    public void objs() {
        getContentPane().setLayout(null);

        c = new JLabel("");
        c.setBounds(100,11,60,20);
        getContentPane().add(c);

        PosicioneElPuntero = new JLabel("Posicione el puntero de su rat\u00F3n");
        PosicioneElPuntero.setBounds(10, 42, 191, 14);
        getContentPane().add(PosicioneElPuntero);

        contadorThread = new ContadorThread(c, 6);
    }

    public void actionPerformed(ActionEvent arg0) {

    }
}

A ver si esto ya soluciona tu problema, espero que tambien te haya quedado claro el tema de los hilos, la solución primera que dí se basa en la misma teoría, solo que utiliza una clase más preparada SwingWorker que tambien son hilos.

Saludos

2votos

xabe Puntos2180

Hola

A ver sí me enterado del problema lo que quieres es ir mostrado por pantalla una secuencia de valores, es decir un contrador?? Si es así a lo mejor este código te puede ayudar.

import java.awt.EventQueue;
import java.awt.Point;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.border.EmptyBorder;

@SuppressWarnings("serial")
public class TiempoSleep extends JFrame {
    //AutoClick AC = new AutoClick();
    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TiempoSleep frame = new TiempoSleep();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public TiempoSleep() {
        setLocation(new Point(200, 200));
        setLocationRelativeTo(null);
        setResizable(false);
        final byte tiempo = 5;

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 212, 164);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JLabel Sleep = new JLabel();
        Sleep.setFocusable(false);
        Sleep.setBounds(58, 11, 81, 54);
        contentPane.add(Sleep);

        JLabel lblPosicioneElPuntero = new JLabel("Posicione el puntero de su rat\u00F3n");
        lblPosicioneElPuntero.setBounds(10, 76, 191, 14);
        contentPane.add(lblPosicioneElPuntero);

        final TareaContador task = new TareaContador(tiempo, Sleep);        
        task.execute();

    }

    class TareaContador extends SwingWorker<Void, Integer> {
      private static final int DELAY = 1000;
      private int tiempo;
      private JLabel tiempoEtiqueta;

      public TareaContador(int tiempo, JLabel tiempoEtiqueta) {
        this.tiempo = tiempo;
        this.tiempoEtiqueta = tiempoEtiqueta;
      }

      @Override
      protected Void doInBackground() throws Exception {
        int i = 0;
        while (!isCancelled() && i < tiempo) {
          i++;
          publish( i);
          setProgress(i);
          Thread.sleep(DELAY);
        }
        return null;
      }   

      protected void process(List<Integer> values) {
        tiempoEtiqueta.setText(values.get(values.size() - 1).toString());
      }

      @Override
      protected void done() {
        if (isCancelled())
          System.out.println("Cancelado !");
        else
          System.out.println("Teminado !");
      }
    }
}

Lo que hago es utilizar la la clase SwingWorker que sirve para hacer tareas pesadas y dejar el hilo principal de swing libre, es decir que no sé quede bloqueado hasta que termine la tarea.

Saludos

0voto

Yesod comentado

Voy a mirarme tu código porque hay cosas que no entiendo a simple vista...

Gracias :D

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta