我正在学习使用显示时间减少的 GUI 实现倒数计时器。我正在使用Groovy的@Bindable
,希望时间减少的变化可以自动显示在相应的UI标签中。
倒计时时间值的减少是在定时器线程中完成的,与 UI 线程分开。但是,倒数计时器不会在 UI 中更新。
正确更新 UI 中的倒计时时间的适当方法是什么?
import groovy.swing.SwingBuilder
import java.awt.FlowLayout as FL
import javax.swing.BoxLayout as BXL
import javax.swing.JFrame
import groovy.beans.Bindable
import java.util.timer.*
// A count-down timer using Bindable to reflcet the reduction of time, when the reduction is done in a TimerTask thread
class CountDown {
int delay = 5000 // delay for 5 sec.
int period = 60*1000 // repeat every minute.
int remainingTime = 25*60*1000
// hope to be able to update the display of its change:
@Bindable String timeStr = "25:00"
public void timeString () {
int seconds = ((int) (remainingTime / 1000)) % 60 ;
int minutes =((int) (remainingTime / (1000*60))) % 60;
timeStr = ((minutes < 9) ? "0" : "") + String.valueOf (minutes) + ":" + ((seconds < 9) ? "0" : "") + String.valueOf (seconds)
}
public void update () {
if (remainingTime >= period)
remainingTime = (remainingTime - period)
// else // indicate the timer expires on the panel
// println remainingTime
// convert remainingTime to be minutes and secondes
timeString()
println timeStr // this shows that the TimerTaskCountDown thread is producting the right reduction to timeStr
}
}
model = new CountDown()
class TimerTaskCountDown extends TimerTask {
public TimerTaskCountDown (CountDown modelIn) {
super()
model = modelIn
}
CountDown model
public void run() {
model.update() // here change to model.timeStr does not reflected
}
}
Timer timer = new Timer()
timer.scheduleAtFixedRate(new TimerTaskCountDown(model), model.delay, model.period)
def s = new SwingBuilder()
s.setVariable('myDialog-properties',[:])
def vars = s.variables
def dial = s.dialog(title:'Pomodoro', id:'working', modal:true,
// locationRelativeTo:ui.frame, owner:ui.frame, // to be embedded into Freeplane eventually
defaultCloseOperation:JFrame.DISPOSE_ON_CLOSE, pack:true, show:true) {
panel() {
boxLayout(axis:BXL.Y_AXIS)
panel(alignmentX:0f) {
flowLayout(alignment:FL.LEFT)
label text: bind{"Pomodoro time: " + model.timeStr}
}
panel(alignmentX:0f) {
flowLayout(alignment:FL.RIGHT)
button(action: action(name: 'STOP', defaultButton: true, mnemonic: 'S',
closure: {model.timeStr = "stopped"; vars.ok = true//; dispose() // here the change to model.timeStr gets reflected in the label
}))
}
}
}