Таймер обратного отсчета с графическим интерфейсом с использованием SwingWorker - не обновляется должным образом

я пытаюсь сделать таймер обратного отсчета с помощью swingworker, проблема в том, что когда секунды доходят до нуля, программы возвращают их к 60 и вычитают один. Я сделал программу без графического интерфейса, и она работает просто отлично, но с помощью swingworker мой таймер выглядит так это

1: 0: 2
1: 0: 1
0: 59: 60

что немного неправильно и должно быть
1: 0: 1
1: 0: 0
0: 59: 59

Оба моих класса основаны на одной и той же логике. Я думаю, это как-то связано с отправкой всего объекта Time в «процесс», но я просто не могу объяснить это себе.

Метод doInBackground():

protected Void doInBackground() throws Exception {
            Integer hours = Integer.parseInt(hoursField.getText());
            Integer minutes = Integer.parseInt(minutesField.getText());
            Integer seconds = Integer.parseInt(secondsField.getText());

            Time time = new Time(hours, minutes, seconds);

            if(minutes < 59 & seconds < 59) {               
                if(hours >=0 & minutes >=0 & seconds >=0) {
                    boolean count = true;
                    while(count) {
                        try {
                            Thread.sleep(1000);
                        } catch(InterruptedException e) {
                            Logger.getLogger(Chronometer.class.getName()).log(Level.SEVERE, null, e);
                        }
                        time.setSeconds(time.getSeconds() - 1);
                        publish(time);
                        if(time.getHours() == 0 & time.getMinutes() == 0 & time.getSeconds() == 0) {
                            count = false;
                        }
                        if(time.getSeconds() == 0) {
                            time.setSeconds(60);
                            if(time.getMinutes() != 0) {
                                time.setMinutes((time.getMinutes() - 1));
                            }else if(time.getMinutes() == 0) {
                                time.setHours((time.getHours() - 1));
                                if(time.getHours() >= 0) {
                                    time.setMinutes(59);
                                }                                    
                                if(time.getHours() < 0) {
                                    time.setHours(0);
                                }
                            }
                        }

                    }
                }else {
                    System.exit(0);
                }
            }
            return null;
        }

И это простой класс Java, который работает по той же логике:

boolean count = true;
        while(count) {
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) {

            }
            seconds--;
            System.out.println(hours + ": " + minutes + ": " + seconds);
            if(hours == 0 & minutes == 0 & seconds == 0) {
                count = false;
            }
            if(seconds == 0) {
                seconds = 60;
                if(minutes != 0){ 
                    minutes--;
                }else if(minutes == 0) {
                    hours--;
                    if(hours >=0){
                        minutes = 59;
                    }                    
                    if(hours < 0) {
                        hours = 0;
                    }
                } 
            }
        }

Если кто-то может указать мне на мою ошибку, я был бы очень благодарен. Спасибо

Добавление метода процесса

public void process(List<Time> time) {
            for(Time t : time) {                    
                showField.setText(String.valueOf(t.getHours()) + ": " + String.valueOf(t.getMinutes())+ ": " + String.valueOf(t.getSeconds()));
            }
        }

person machekj    schedule 22.01.2014    source источник
comment
время.setSeconds(60); должно быть time.setSeconds(59);   -  person Typo    schedule 22.01.2014


Ответы (2)


твоя линия

if(time.getSeconds() == 0) time.setSeconds(60);

должно быть

if(time.getSeconds() == 0) time.setSeconds(59);

И инвертируйте эти буксирные линии:

time.setSeconds(time.getSeconds() - 1);
publish(time);

нравится:

publish(time);
time.setSeconds(time.getSeconds() - 1);

Вывод правильный, но он не показывает результат, потому что, когда секунды достигают нуля, условное выражение выполняется, не показывая промежуточное время.

Измените эту строку:

 if(time.getSeconds() == 0)

для этого:

 if(time.getSeconds() < 0)

И это:

 if(time.getHours() == 0 & time.getMinutes() == 0 & time.getSeconds() == 0)

 if(time.getHours() == 0 & time.getMinutes() == 0 & time.getSeconds() < 0)
person Typo    schedule 22.01.2014
comment
1:0:2 1:0:1 0:59:59 Опять неправильный вывод, это не логическая проблема, программа работает без SwingWorker(просто печать на консоли) и ничего страшного, я думаю это как-то связано отправка класса Time в процесс и печать идет правильно без корректного вычета. - person machekj; 22.01.2014
comment
@Radoslav добавил к ответу - person Typo; 22.01.2014
comment
1 0 2 1 0 1 0 59 59 Тем не менее, намного лучше, но работает не так, как предполагалось... и я сомневаюсь в порядке строк. Я сделал ту же программу без swingworker и его метода (только печатает строки на консоли), и она работает просто отлично ... вот что меня смущает ... может быть, при отправке времени объекта для обработки и переборе всего списка. .. - person machekj; 22.01.2014
comment
@Radoslav добавил к ответу - person Typo; 22.01.2014
comment
Наконец-то сработало, кажется, это был не SwingWorker, спасибо за ваше время, приятель, подумал, что я ушел, если (time.getHours() == 0 & time.getMinutes() == 0 & time.getSeconds() == 0), чтобы он мог закончить в 0:0:0 и он все еще работает, большое спасибо! - person machekj; 22.01.2014

Я не вникал в вашу логику, но вы можете добиться того же, используя Calendar, который выглядит более простым.

    Calendar c = Calendar.getInstance();
    c.set(Calendar.HOUR_OF_DAY, hours);
    c.set(Calendar.MINUTE, minutes);
    c.set(Calendar.SECOND, seconds);
    SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss");

    Date d = c.getTime();
    System.out.println(format.format(d)); 
    while(count) {
        c.set(Calendar.SECOND, c.get(Calendar.SECOND)-1); //decrement 1 second at a time
        d = c.getTime();
        System.out.println(format.format(d)); 
        Thread.sleep(1000); //Pause for a second between each print
    }

Я использовал SimpleDateFormat("HH:mm:ss") для простоты. Если вам нужны разные поля времени, вы можете использовать метод Calendar.get(..), чтобы получить то же самое

person sanbhat    schedule 22.01.2014
comment
Я получаю ввод из формы, где вы вводите значения в текстовые поля, затем программа должна начать обратный отсчет, пока не достигнет нуля, я не публиковал всю свою программу. - person machekj; 22.01.2014
comment
hours, minutes, seconds правильно ли вы вводите?.. если вы видите в строке 2,3,4, я использую то же самое - person sanbhat; 22.01.2014