为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Swing-GUI 和 WebApplication(如 Vaadin 或本机 JS)

如何在 Swing-GUI 和 WebApplication(如 Vaadin 或本机 JS)

慕少森 2023-06-21 13:13:15
我正在尝试将倒计时从 Java 应用程序同步到浏览器。倒计时可以随时停止、开始和重置。我试图在 Vaadin 13 中实现这一点,但无法访问 UI 访问方法来锁定 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}这似乎是一种不可靠且低效的方式
查看完整描述

1 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

/*

    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;

    }

}

我展示这个是因为如果你仔细观察它,你会发现这个东西的整个状态由两个数字和一个布尔值组成,它们只会在你做某事时改变,比如开始/停止它。


实际值是根据该状态和计算机内部时钟计算得出的。


因此,如果您在前端和后端之间同步此状态,它们都会(大部分)同步运行。


为什么大部分?因为在另一端收到新状态之前有一点延迟。在这几毫秒内,两者不同步。一旦另一端更新了它的状态,它们就会再次同步。


查看完整回答
反对 回复 2023-06-21
  • 1 回答
  • 0 关注
  • 87 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信