【问题标题】:JLabel Icon not updating with setIcon (or other redundancies)JLabel 图标未使用 setIcon 更新(或其他冗余)
【发布时间】:2013-06-16 02:37:32
【问题描述】:

如前所述,我正在使用两种不同版本的代码,第一个工作正常,没有任何问题,第二个,唯一没有发生的事情是更新图像(已验证通过逐步调试和调试打印手动验证所有值和条件)

            /* properly updates dice[] JLabel icons */

            for (int i = 0; i < game.getToRoll(); i ++){
                    //sets rolled dice to actual values
                    dice[i].setIcon(dicePic[(game.getDice(i).getFaceValue())]);    
            }

            /* loops properly, generates properly, does not update icons */

            Die x = new Die();
            int animate = 0;

            while(animate < 10){
                    for (int i = 0; i < 6; i++ ){
                            x.roll();

                            if (i <= (game.getToRoll() -1))
                                    dice[i].setIcon(dicePic[x.getFaceValue()]);                            
                            else   
                                    dice[i].setIcon(dicePic[0]);
                    }
                    panel[1].repaint();
                    panel[1].validate();

                    animate++;
                    try{
                            Thread.sleep(100);
                    }
                    catch(Exception e){
                            e.printStackTrace();
                    }
            }

我一直在寻找导致问题的某种想法,除了“有时重新绘制和验证会修复不起作用的问题”之外,我没有遇到任何其他问题。

如上所述,调试为我提供了完全按预期工作的代码流的绿灯,在第二个示例中只是空图像图标。

【问题讨论】:

  • 下次别忘了添加java 标签,因为对于这个问题,这比任何其他标签都更重要。我已经添加了它。
  • 不需要 repaint() 和 revalidate() 因为组件会在图标更改时自动执行此操作。此外,正确的顺序是 revalidate() 和 repaint(),因为您首先需要在重新绘制组件之前调用布局管理器。
  • 可能没有必要,但我在这里找到了关于 Swing 无法按预期工作的线程,并且有时使用其中一种或两种方式可以解决问题。但是,感谢您提供有关它的信息,比盲目修复更好地了解我在做什么。

标签: java swing icons jlabel


【解决方案1】:

问题是Thread.sleep(100); 图标确实发生了变化,但您看不到变化,因为您阻止了 UI 线程。

所以规则是:永远不要让 EventDispatchThread 休眠!

我的建议是使用Timer:

new javax.swing.Timer(200, new ActionListener() {
    @Override
    public void actionPerformed(final ActionEvent e) {
        //do an icon change
    }
}).start();

【讨论】:

  • 我最初尝试过,似乎由于尝试使用以动画计数器为条件的while循环而阻止了计时器对象的发生,因此一旦循环命中,尽管如此,其他任何事情都不会发生计时器先来。我很乐意尝试(重新)实现一个计时器,但我不明白为什么暂时停止线程不会在任何时候更新图标。我也不明白为什么我之前的计时器实现不起作用,我对正常代码流的理解很好,但感觉就像是在摆动队列中而不是在执行中。
  • 我必须重构代码来实现定时器的这种新用法,并且我将它封装在它自己的方法中,但是该方法给出“无法从 void 转换为定时器”。或者,有什么方法可以自我引用这个新计时器,因为我能想到的唯一方法是在不回到以前不起作用的方法的情况下实现它,就是从内部停止计时器。
  • 嗯,无论如何,使用计时器有效,但按照建议实施它没有。所以感谢你让我放弃一些我还没有被教导为什么它不起作用的东西,并让我有理由必须调试才能让它工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多