简体   繁体   中英

Java timer delay not working properly

I'm trying to use timer delay from the javax.swing.Timer class.
I'm trying to have a label (a temperature) in a JFrame updated every 5 seconds, however the label sometimes gets updated in 1 second. I want it to happen only in 5 seconds.
Here is a portion of my code:

int delay = 5000;           //milliseconds    
ActionListener taskPerformer = new ActionListener() {
                  public void actionPerformed(ActionEvent evt) {
                        tempLabel.setVisible(true);
                        String currTemp = null; //current temperature
                        try {
                            currTemp = getWeatherData.getTemp(locationIndex);
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        tempLabel.setText("Temperature :  " + currTemp);
                  }
              };
              Timer timer= new Timer(delay, taskPerformer);
              timer.setRepeats(true);
              timer.start();  

What's happening? Thanks for reading

Haven't used Timer object from swing. But from what i can read, the "delay" you are using, is actually speed?

https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html

Look into timer.setInitialDelay(pause); instead

//EDIT:

Might have to give it a delay in between every 'successful run' instead of just:

Timer timer= new Timer(delay, taskPerformer); 
timer.setDelay(delay); 
timer.setRepeats(true); 
timer.start(); 

The amount of time can be affected by a number of things. It's important to remember, a Timer is not accurate, it's only suppose to guarantee a minimum amount of time between ticks.

However, because Timer tick within the context of the EDT and I have no idea what getWeatherData.getTemp is actually doing, it's possible that it's blocking the EDT and preventing the UI from been updated ... or a whole bunch of other things in your code which you're not showing us.

It might be better to use a SwingWorker

public class TempatureWorker extends SwingWorker<Void, String> {

    private int locationIndex;

    public TempatureWorker(int locationIndex) {
        this.locationIndex = locationIndex;
    }

    @Override
    protected Void doInBackground() throws Exception {
        while (!isCancelled()) {
            publish(getWeatherData.getTemp(locationIndex));
            Thread.sleep(5000);
        }
        return null;
    }

    @Override
    protected void process(List<String> values) {
        String last = values.get(values.size() - 1);
    }

}

You have to work out how you want to update the UI from here, so long as you're doing from process method. You could pass a reference of the JLabel to the worker, but I'd be tempted to use an observer pattern instead, as it decouples the worker.

See Worker Threads and SwingWorker for more details

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