微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Java Thread.sleep / Timer / TimeUnit不起作用

如何解决Java Thread.sleep / Timer / TimeUnit不起作用

我在做一个有趣的小项目时遇到了一些麻烦:我要实现的目标是,在字符串输出到每次绘制一个字符(转换为String)之间存在几秒钟的延迟,为了给人一种输入它的错觉(在JFrame中)。但是,似乎for循环(请参见下文)首先执行等待的总添加时间,然后立即绘制整个字符串,无论我使用哪种已尝试的解决方案(try and catch + Thread.sleep,{{1} }或TimeUnitjava.swing.timer)。 这仍然是我使用Java的第一个项目,因此如果代码完全混乱,我会道歉。到目前为止,关于stackoverflow的现有解决方案中没有一个我有帮助。 编辑:错误消息(可能不相关)通过变量n应该声明为final的方式告诉我,因为其作用域还不够。在这种情况下,这是行不通的。

java.awt.timer

在此工作部分中仍然存在以下问题:a)每个字符都显示在同一位置而不是增加x值; b)跳过了某些字符(或在它们成对出现之前(三对))。这是代码

@Override
public void paintComponent(Graphics maler) {
    super.paintComponent(maler);
    maler.setColor(Color.WHITE);
    maler.fillRect(0,600,600);
    maler.drawImage(bildchen,37,30,this);
    
    
    maler.setColor(Color.BLACK);
    maler.fillRect(0,600);
    maler.setColor(new Color(32,194,14));
    Font kram = new Font("OCR A Extended",Font.BOLD,40);
    maler.setFont(kram);
    
    
    String text = "WILLKOMMEN!";
    final int  n = 0;
    int p = 90; 
    
    
    
    for (int i= 0; i<=10; i++) {
        
        Timer timer = new Timer();
        
        TimerTask task = new TimerTask() {
            public void run() {
                maler.drawString(Character.toString(text.charat(n)),p,200);
            }
        };
            
        timer.scheduleAtFixedrate(task,1000,1000); 
         
        p = p+34;
        n++; 
        
        }

解决方法

不幸的是,您尝试制作动画的方式根本上是错误的。

要正确制作动画,您需要以某种方式存储动画的当前状态,并在绘制时使paintComponent使用动画的状态。

在这种情况下,您仅对文本WILLKOMMEN的外观进行动画处理,因此您需要的状态只是一个数字:应该绘制多少个字母。一个AtomicInteger对象可以很好地解决这个问题,因此添加一个AtomicInteger实例变量,并从paintComponent中使用它:

AtomicInteger animationState = new AtomicInteger(0);

@Override
protected void paintComponent(Graphics maler) {
    super.paintComponent(maler);
    String text = "WILLKOMMEN!";
    int p = 90;
    maler.drawString(text.substring(0,animationState.get()),p,200);
}

要实际使组件具有动画效果,您需要定期更改动画状态并使组件重新绘制自身。这可以通过计时器线程来完成。在这种情况下,可以调用incrementAndGet方法将animationState更改为animationState + 1,然后调用repaint()方法以显示更新状态。

Timer timer = new Timer();

void runAnimation() {
    TimerTask task = new TimerTask() {
        public void run() {
            if (animationState.get() < 10) {
                animationState.incrementAndGet();
                repaint();
            } else {
                cancel();
            }
        }
    };
    timer.scheduleAtFixedRate(task,1000,1000);
}

当您希望动画开始时,请调用runAnimation方法。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。