[英]How to synchronize a countdown between a Swing-GUI and a WebApplication like Vaadin or native JS
我正在嘗試將Java應用程序中的倒計時同步到瀏覽器。 倒計時可以隨時停止,啟動和重置。
我嘗試在Vaadin 13中實現此功能,但是無法訪問UI Access Mehtod來鎖定vaadin會話。 現在,我正在嘗試使用本機JS和Ajax請求來實現這一點,但是我不確定如何在不每秒發出一個Ajax請求的情況下同步停止/啟動和重置事件。
這是計數器的Swing實現
public void timer() {
Timer timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (seconds == 0 && minutes > 0) {
minutes--;
seconds = 59;
} else {
seconds--;
}
label.setText(minutes+":"+seconds);
repaint();
}
});
timer.start();
}
現在,我將為JS代碼提供一個Spring Boot Rest API,以詢問剩余的分鍾和幾秒鍾。
setInterval(test, 1000);
async function test() {
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "http://10.0.1.17/countdown", false);
xhttp.send();
//console.log(JSON.parse(xhttp.responseText));
//Do Something with it
}
這似乎是一種不可靠和無效的方法
從我寫的另一個答案中查看該課程
/*
a (pausable) linear equation over real time
value = _speed * Date.now() + _offset;
//when paused, it's simply:
value = _offset;
so basically a clock, a stopwatch, a countdown, a gauge, ...
since it is only a linear equation over time, it is independant of any interval.
It computes the value (using Date.now()) whenever you ask for it. Wether this is ever frame or every hour.
*/
class Clock {
constructor(value=Date.now(), speed=1){
//state; changes only when YOU set one of the properties (value, paused or speed)
this._offset = +value || 0;
this._speed = +speed || 0;
this._paused = true;
//preparing a simple hook to get notified after the state has been updated (maybe to store the new state in the localStorage)
this.onStateChange = undefined;
}
get value(){
return this._paused? this._offset: this._speed*Date.now() + this._offset
}
set value(arg){
let value = +arg || 0;
let offset = this._paused? value: value - this._speed * Date.now();
if(this._offset !== offset){
this._offset = offset;
if(typeof this.onStateChange === "function")
this.onStateChange(this);
}
}
get speed(){
return this._speed
}
set speed(arg){
let speed = +arg || 0;
if(this._speed !== speed){
if(!this._paused)
this._offset += Date.now() * (this._speed - speed);
this._speed = speed;
if(typeof this.onStateChange === "function")
this.onStateChange(this);
}
}
get paused(){
return this._paused
}
set paused(arg){
let pause = !!arg;
if(this._paused !== pause){
this._offset += (pause? 1: -1) * this._speed * Date.now();
this._paused = pause;
if(typeof this.onStateChange === "function")
this.onStateChange(this);
}
}
time(){
let value = this.value,v = Math.abs(value);
return {
value,
//sign: value < 0? "-": "",
seconds: Math.floor(v/1e3)%60,
minutes: Math.floor(v/6e4)%60,
hours: Math.floor(v/36e5)%24,
days: Math.floor(v/864e5)
}
}
valueOf(){
return this.value;
}
start(){
this.paused = false;
return this;
}
stop(){
this.paused = true;
return this;
}
}
之所以顯示它,是因為如果您仔細查看它,您會發現該事物的整個狀態由兩個數字和一個布爾值組成,並且僅當您執行某項操作(例如啟動/停止它)時它們才會改變。
實際值是根據此狀態和計算機內部時鍾計算得出的。
因此,如果您在前端和后端之間同步此狀態,則它們都會(大部分)同步運行。
為什么大多數? 由於在另一端收到新狀態之前的延遲很小。 對於這幾毫秒,兩者不同步。 另一端更新狀態后,它們將再次同步。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.