1

I'm trying to create a Java GUI which displays the current time. Currently, I can make it display the current time, but only on startup. It then simply remains on that time forever. The reason is that I cannot figure out how to make it automatically load in the new current time every second. Here is my relevant code thus far:

// Getting the current time...
long epoch = System.currentTimeMillis() / 1000;
String date = new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date(epoch * 1000));

// Creating the panel...
JLabel lblThetime = new JLabel(date);
sl_panel.putConstraint(SpringLayout.NORTH, lblThetime, 55, SpringLayout.SOUTH, lblIBeA);
sl_panel.putConstraint(SpringLayout.WEST, lblThetime, 139, SpringLayout.WEST, panel);
lblThetime.setFont(new Font("Avenir Next", Font.PLAIN, 40));
    
// Adding the time to the panel
panel.add(lblThetime);
    
// My refresher which doesn't work
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        removeAll();
        validate();
        repaint();
    }
}, 1000, 1000);

I attempted to make a refresher using information from this thread, but to no avail, the window (when run) is just blank. I then tried making a different refresher using information from this thread, and created this:

// My refresher which doesn't work
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        contentPane.remove(lblThetime);
        contentPane.add(lblThetime);
    }
}, 1000, 1000);

With contentPane having been defined as private JPanel contentPane;

Which also didn't work, however only the time itself is blank, the rest of the content in the window (One other JLabel (just some text)) remains as normal.

Without any refresher it behaves as described above, whereby it just displays the time when it started and remains on that time forever.

I'm using Eclipse with WindowBuilder. (And I'm (probably evidently) a complete noob to Java GUI stuff xD)

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
edo
  • 99
  • 1
  • 2
  • 15

6 Answers6

4

I discovered the solution!

I tried all the solutions given as answers here, and none which gave code fully worked, however all answers pointed me in the right direction. I found the solution to the problem on a website which I have forgotten the name of, but I used its suggestion and came up with this final solution which worked:

        // New timer which works!
    int delay = 1000; //milliseconds
      ActionListener taskPerformer = new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
              String date = new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date(System.currentTimeMillis()));
              lblThetime.setText(date);
          }
      };
      new Timer(delay, taskPerformer).start();

Thank you to all who answered as without said answers I probably would not have been able to find this solution :D

Dharman
  • 30,962
  • 25
  • 85
  • 135
edo
  • 99
  • 1
  • 2
  • 15
  • Your problem was caused by not using setText - which he clearly points out. Also I believe that since he led you to the correction of the code he deserves some credit. – Christian Fries Nov 04 '13 at 09:12
  • 1
    *Because it didn't solve the problem, it only pointed me in the right direction.* Warby you'll see a lot of answers in SO which just lead OP to the right way and don't give directly the "working code", because the goal is learn from peers and not getting our work done by others. For instance see this [Q&A](http://stackoverflow.com/questions/19732777/is-jlist-override-the-list-automatic-bug). *PS:* thanks @ChristianFries :) – dic19 Nov 04 '13 at 13:53
  • No worries, all we keep learning about this site every day :P And I'm happy you did solve your problem by yourself instead of copy/paste another person's code. Keep in this way! :D – dic19 Nov 04 '13 at 19:50
2

First of all you are using java.util.Timer instead of javax.swing.Timer. You need use this second class when working with Swing components to ensure GUI updates are made on the Event Dispatch Thread. Also take a look to Concurrency in Swing tutorial.

As suggested in other answers, there is no need to remove/add JLabel each time you want to update its text. Just call JLabel.setText() method.

If you still want remove/add the JLabel each time, then be aware of this:

From Container.add() javadoc:

This method changes layout-related information, and therefore, invalidates the component hierarchy. If the container has already been displayed, the hierarchy must be validated thereafter in order to display the added component.

Then you'll need to call Component.revalidate() method. Like this:

contentPane.remove(lblThetime);
contentPane.add(lblThetime);
contentPane.revalidate();
dic19
  • 17,821
  • 6
  • 40
  • 69
0

Instead of removing and adding the label to the panel you should change the string of the label every second.

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
       String date = new java.text.SimpleDateFormat("HH:mm:ss").format(new java.util.Date() );

       lblThetime.setText(date);
    }
}, 1000, 1000);



// Creating the panel...
JLabel lblThetime = new JLabel(date);
kerberos84
  • 300
  • 1
  • 10
0

You can try to use Swing Timer for that task, for example:

private static JLabel l;

public static void main(String[] args) {

    Timer timer = new Timer(1000, new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            l.setText(new Date().toString());
        }
    });
    timer.start(); 
    JFrame f = new JFrame();
    l=new JLabel(new Date().toString());
    f.getContentPane().add(l);

    f.pack();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.setVisible(true);
}

That example update JLabel with new date every second

alex2410
  • 10,904
  • 3
  • 25
  • 41
0
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {
        label.setText(new Date().toString());
    }
}, 1000, 1000);

Isn't it simpler?

-2

Clue 1: really search for Timer classes in Java. Did you pick the correct one?

Clue 2: update the label text instead.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Kili Liam
  • 9
  • 1
  • 3
    Hi there Kili Liam. Welcome to SO and thanks for participating but that's not how SO works... Here you're not supposed to answer questions with riddles and other questions and certainly not by giving "clues" in a "RTFM" style. Here you answer questions with... answers! You're also not supposed to end your answers with neither "Hope It Helps" abbreviated to "HIH" nor with your name abbreviated. If you don't know or don't want to give the correct answer, then you simply do not post. If you want to comment (instead of answer), you can use comments (once you have gained some rep). – TacticalCoder Nov 01 '13 at 13:58