繁体   English   中英

Java Thread.sleep/Timer/TimeUnit 不工作

[英]Java Thread.sleep/ Timer/ TimeUnit not working

我在我的一个有趣的小项目中遇到了一些麻烦:我想要实现的是在字符串输出之间延迟几秒钟,因此一次绘制一个字符(转换为字符串),以便给人一种输入它的错觉(在 JFrame 中)。 然而,它似乎是 for 循环(见下文),首先执行总增加的等待时间,然后一次绘制整个字符串,无论我使用哪种尝试过的解决方案( try and catch + Thread.sleepTimeUnitjava.swing.timerjava.awt.timer )。 这仍然是我在 Java 中的第一个项目之一,所以如果代码一团糟,我深表歉意。 到目前为止,stackoverflow 上现有的解决方案都没有帮助我。 编辑:错误消息(可能不相关)告诉我变量 n 应该声明为 final,因为它的范围不够。 这在这种情况下不起作用。

@Override
public void paintComponent(Graphics maler) {
    super.paintComponent(maler);
    maler.setColor(Color.WHITE);
    maler.fillRect(0, 0, 600, 600);
    maler.drawImage(bildchen, 37, 30, this);
    
    
    maler.setColor(Color.BLACK);
    maler.fillRect(0, 0, 600, 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++; 
        
        }

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

AtomicInteger animationState = new AtomicInteger(0);
@Override
public void paintComponent(Graphics maler) {
    super.paintComponent(maler);
    maler.setColor(Color.WHITE);
    maler.fillRect(0, 0, 600, 600);
    maler.drawImage(bildchen, 37, 30, this);
    
    
    maler.setColor(Color.BLACK);
    maler.fillRect(0, 0, 600, 600);
    maler.setColor(new Color(32, 194, 14));
    Font kram = new Font("OCR A Extended", Font.BOLD, 40);
    maler.setFont(kram);
    
    int p = 90; 
    String text = "WILLKOMMEN!";
    maler.drawString(Character.toString(text.charAt(animationState.get())), p, 200);
    runAnimation();
}


        Timer timer = new Timer();
        

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

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

正确的动画制作方式,需要通过某种方式存储动画的当前状态,让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方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM