Java jProgressBar进度条的玄学

辛明影老师的Java选修课相关。


记忆测试小游戏内容及流程见这一篇博文:C语言 记忆测试(Memory Test)小游戏的实现

本次使用Java实现,遇到了一个问题:
对于字符串消失操作及进度条的设计。
字符串消失的操作需要新建一个线程令其sleep一定时间,如下:

 Thread t1 = new Thread(new Runnable() {
            public void run() {
                try {
                    jLabel1.setText(num);
                    jTextField1.setEditable(false);
                    Thread.sleep(time);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                jTextField1.setEditable(true);
                jLabel1.setText("");
                num_c = num;
                num = "";
            }
        });
        t1.start();
        time += 1000;
        len += 2;

*这里jTextField1.setEditable(true);num = ""; 必须放到run里面,不然jTextField1一直无法编辑,num也不清零。但是后面的time += 1000;len += 2;却可以执行。。?

进度条的设计大概经历如下:

1、一开始进度条的设计是同时在另一个线程中进行。如下:

 t1.start();
         jProgressBar1.setMinimum(0);
        jProgressBar1.setMaximum(time/10);
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i <=time/10 ; i++) {
                    try {
                        Thread.sleep(10);
                        jProgressBar1.setValue(i);
                    } catch (InterruptedException e) {
                    }
                }
            }
        });
        t2.start();

理论上说进度条的进行应该是和字符的出现消失完全同步的。结果t2运行的时间却总是不等于t1。初步怀疑是由于sleep精度不足所致,100个10ms不等于1000ms。但是有一个奇怪的现象,time设为1000ms时进度条运行过快;time设为10000ms使进度条却又运行过慢。这似乎说明这不是简单的精度问题。

2、 以为是精度原因,所以为保证进度条和字符的出现消失完全同步,只能降低时间精度要求,采取进度条结束时字符消失的方法,两个线程变成一个线程总不能再有差距了吧。最终代码如下:

  jProgressBar1.setMinimum(0);
  jProgressBar1.setMaximum(time/10);
  Thread t2 = new Thread(new Runnable() {
  public void run() {
         jLabel1.setText(num);
             jTextField1.setEditable(false);
         for (int i = 0; i <time/10 ; i++) {
             try {
                 Thread.sleep(10);
                 jProgressBar1.setValue(i);
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
         }
         jTextField1.setEditable(true);
         jLabel1.setText("");
         num_c = num;
         num = "";
     }
 });
 t2.start();         //启动线程t2
 time += 1000;
 len += 2;

结果仍不尽人意,进度条无论设置为多少都过快。也就是说,for循环最后一轮的jProgressBar1.setValue(i);结束后并没有马上执行jTextField1.setEditable(true);

3、探究原因时,在时间为1000ms的条件下,把for循环的次数从time/10改到time/20,折半,出乎意料地运行成功了,进度条和字符消失对上了。而如果把sleep的时间折半,却没有成功。时间改为10000ms,奇妙的事情出现了,进度条停止在一半多一点点处,而且进度条停止时字符还是恰好消失。time改为1000ms到10000ms的其他时间,进度条有规律地停在50%到100%的不同位置。时间改为10000ms以上,发现进度条越来越接近50%,也就是理论上来说正常应该停的地方。具体为1000ms 100%,2000ms 75%,3000ms 66%,······但是,1000ms一下也是100%,也就是1000ms时进度条可能超过了100%,事实也是如此。

4、进度条总长度倍增观察,和第三条结果一样。

5、进度条总长度倍增,time设为1000ms,发现sleep不论多少,100%处正好字符消失,只不过快慢不同。

有待研究。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值