Java将打字机效果添加到JTextArea

Java将打字机效果添加到JTextArea,java,swing,timer,Java,Swing,Timer,我需要一次显示一个JTextArea的输出,每个字符之间有一点延迟。我的尝试如下: private static void printInput(final String input) { Timer timer = new Timer(60,new ActionListener(){ public void actionPerformed(ActionEvent e) { for(int i =

我需要一次显示一个JTextArea的输出,每个字符之间有一点延迟。我的尝试如下:

 private static void printInput(final String input)
{
        Timer timer = new Timer(60,new ActionListener(){
            public void actionPerformed(ActionEvent e)
            {
                for(int i = 0; i<input.length(); i++)
                {
                    messageArea.append(Character.toString(input.charAt(i)));
                }
            }
        });
}
也有类似的问题,但我找不到一个例子来解决我的问题

计时器是一个伪循环,它在预定义的延迟后触发一个循环,每个循环都是循环的一次迭代,每次迭代都需要更新UI和更新迭代器值

现在,因为我不喜欢在静态上下文中工作,我建议的第一件事是将基本概念封装到一个单独的类中。通过这种方式,您可以轻松地封装状态

public class TypeWriter {
    private Timer timer;
    private int characterIndex = 0;
    private String input;
    private JTextArea textArea;

    public TypeWriter(JTextArea textArea, String input) {
        this.textArea = textArea;
        this.input = input;
        timer = new Timer(60, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (characterIndex < input.length()) {
                    textArea.append(Character.toString(input.charAt(characterIndex)));
                    characterIndex++;
                } else {
                    stop();
                }
            }
        });
    }

    public void start() {
        textArea.setText(null);
        characterIndex = 0;
        timer.start();
    }

    public void stop() {
        timer.stop();
    }

}

因此,这是非常基本的,所有这一切都是,使用计时器,检查是否有更多的字符需要打印,如果有,它采取下一个字符,并将其附加到文本区域,并更新迭代器值。如果我们在本文的末尾,它将停止计时器ie,退出条件

计时器是伪循环,也就是说,每个循环都是循环中的一个迭代,这意味着您需要更新UI,更新循环条件并根据需要重复。非常感谢您的快速响应,并提供了一个工作示例。开始时,这会将文本区域设置为null,我假设可以安全地忽略此行为?@BenKramer它会将文本设置为null,是的,当您想要清除文本组件时,这是一种常见的做法。你可以用它来得到同样的结果;由于文本组件的工作方式,它们永远不会从getTextI返回null。我尝试创建两个在同步关键字下管理的实例,如下所示:SynchronizedMessageGearEA{new TypeWriterMessageGearEA,Testing.start;new TypeWriterMessageGearEA,“在宇宙诞生之初,这让很多人非常恼火,并被广泛认为是一个糟糕的举动。”-Douglas Adams.start;但是这并不强迫每个人“等待轮到自己”不,我不这么认为。我会在TypeWriter类中添加一个观察者模式,它可以生成开始/停止事件,然后启动第一个类,当它触发停止事件时,启动下一个,基本上是将一个链接到另一个。我不擅长编程这种方法对我来说似乎有点雄心勃勃。是否有一种不那么雄心勃勃的方法,即使效率较低,我也可以尝试?