简体   繁体   中英

JLabel not updating with timer

I have searched all over the internet trying to find how to make an automatic updating clock gui program with no luck. I have tried many different methods, ending with the same results. I am using the swing Timer as I have read that's the best way to deal with gui's. I have tried validate(), revalidate(), repaint(). Here is part of the code:

import javax.swing.*;
//import java.awt.event.*;
import java.util.*;
import javax.swing.Timer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ClockPanel extends JPanel { 
    Calendar now = Calendar.getInstance();
    int hour = now.get(Calendar.HOUR_OF_DAY);
    int minute = now.get(Calendar.MINUTE); 
    int second = now.get(Calendar.SECOND);
    int month = now.get(Calendar.MONTH) + 1;
    int day = now.get(Calendar.DAY_OF_MONTH);
    int year = now.get(Calendar.YEAR);

    private String currentTime;
    private JLabel current;

    public ClockPanel() {
        super();
        currentTime = getTime();
        current = new JLabel(currentTime);
        add(current);

        ActionListener updater = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                getTime();
                if(second == 60){
                    current.setText(currentTime);
                    revalidate();

                }
                getTime();
            }
        };
        Timer timer = new Timer(1000, updater);
        timer.start();
    }

This is the final code that I have ended up with; I know it's wrong, but I have changed it so much for hours that I gave up. Thanks

EDIT: Here's the rest of the code

public String getTime() {
        String time;
        String period = "AM";
        String monthName = "";
        switch(month) {
            case (1):
                monthName = "January";
                break;
            case (2):
                monthName = "February";
                break;
            case (3):
                monthName = "March";
                break;
            case (4):
                monthName = "April";
                break;
            case (5):
                monthName = "May";
                break;
            case (6):
                monthName = "June";
                break;
            case (7):
                monthName = "July";
                break;
            case (8):
                monthName = "August";
                break;
            case (9):
                monthName = "September";
                break;
            case (10):
                monthName = "October";
                break;
            case (11):
                monthName = "November";
                break;
            case (12):
                monthName = "December";
                break;
        }
        if(hour >= 12){
            period = "PM";
        }
        time = monthName + " " + day + ", " + year + " "
                + hourCheck(hour) + ":" + minuteCheck(minute) + period;
        return time;
    }

    private int hourCheck(int hour) {
        if(hour > 12){
            hour -= 12;
            return hour;
        }
       if(hour == 0) {
            hour += 12;
            return hour;
        }
       return hour;
    }

    private StringBuilder minuteCheck(int minute) { 
       StringBuilder time = new StringBuilder();

       if(minute < 10) {
           return time.append("0").append(minute);
       }
       else {
           time.append("").append(minute);
       }
       return time;
    }

}

You're calling getTime() , but ignoring what it returns. The current time thus stays as it was before. Replace your code with:

    ActionListener updater = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent event) {
            String newTime = getTime();
            current.setText(newTime);
        }
    };

EDIT :

Not only do you ignore the value returned by getTime() , but getTime() also always returns the same thing, since you're always reuse the month, minute, seconds, etc. that have been initialized only once, when the panel has been constructed. You're also making your life really difficult by not using the standard DateFormat class.

Remove ALL the fields from your panel except the JLabel, and change the getTime() method to something like this:

private String getTime() {
    // get the CURRENT date:
    Date currentDate = new Date();

    // format it and return it:
    return new SimpleDateFormat("MMMM dd, yyyy hh:mm a").format(currentDate);
}

You could adjust your code to this and it will work:

public class ClockPanel extends JPanel { 
    private final JLabel current;

    public ClockPanel() {
        current = new JLabel(now());
        add(current);

        new Timer (1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                current.setText(now());
            }
        }).start();
    }

    private static String now() {
        // implement your own
        return new Date().toString();
    }

    public static void main(String[] args) {
        JFrame main = new JFrame("Simple Clock");
        main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        main.setSize(200, 200);
        main.setContentPane(new ClockPanel());
        main.setVisible(true);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM