I am having some issues trying to format my milliseconds to mm:ss format for this little tea timer I'm making. The TimerListener constructor takes in a double which is the milliseconds I'm using for my countdown timer. I then convert that counter variable to a long for I can use it with TimeUnit. However, when I add the hms variable to my JLabel the timer only counts down one second. If I add in the counter variable or the formatTime variable the countdown works fine, but it isn't in the mm:ss format I want. Any help would be greatly appreciated as I am a bit lost at this point.
Mike Stein wrote:The TimerListener constructor takes in a double which is the milliseconds I'm using for my countdown timer.
I think Campbell already covered the business of using a double for your milliseconds, but I actually worry about the whole business of a "countdown" timer.
Java's time "granularity" simply isn't good enough to be able to "count down" from a start point for each invocation. My general rule of thumb is that I don't trust "timed" actions to be accurate to anything more than about a 10th of a second.
Also: This is an ActionListener, and so is presumably triggered by some action on the screen. My guess is that you want to "start" your timer with a mouseclick, and then have it update your screen every second or so, so that it APPEARS to count down. But that's very different from actually implementing it AS a counter.
If I was doing this. I'd probably do something like this:
1. Pass a duration in milliseconds - ie, how long you want it to run for - to my Timer constructor, along with a reference to the screen or component that needs to listen for updates.
2. Initialize an internal final long startTime field with System.currentTimeMillis() at the time it's created.
3. Initialize an internal final long endTime field to startTime + duration at the time it's created.
4. Start a loop that contains a sleep() command based on how often you want to update your component. This loop:
a. Gets the current time and subtracts it from endTime to produce a timeLeft value. If this is negative, the loop terminates.
b. Works out all the TimeUnit fields fot timeLeft, and passes them to the component to be updated (maybe as part of some sort of Event object).
You could possibly achieve the same thing by simply passing a Calendar based on timeLeft.
No counting, and my Timer would be a producer of Events, not a Listener for them.
Just one other point (very minor). Isn't:
TimeUnit.MILLISECONDS.toMinutes(formatTime) % TimeUnit.HOURS.toMinutes(1) the same thing as:
TimeUnit.MILLISECONDS.toMinutes(formatTime) % 60L ?
BTW, that TimeUnit class seems incredibly clunky to me. It doesn't even have an 'extract()' method (ie, exactly what you're trying to do above).
Kind of makes me glad I never knew about it until now...but thanks for bringing it to my attention.
Happy 2016 everyone!
"Leadership is nature's way of removing morons from the productive flow" - Dogbert
Articles by Winston can be found here