TechnicalCustoms TechnicalCustoms - 6 months ago 22
Java Question

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

}

Answer

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