【问题标题】:Java add Typewriter effect to JTextAreaJava 为 JTextArea 添加 Typewriter 效果
【发布时间】:2017-04-10 22:41:21
【问题描述】:

我需要一次显示一个字符到 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)));
                }
            }
        });
}

有类似的问题,但是我找不到可以用来解决问题的示例

【问题讨论】:

  • ATimer是伪循环,即每个循环都是一个循环遍历,也就是说你需要更新UI,更新循环条件,按要求重复

标签: java swing timer


【解决方案1】:

Timer是一个伪循环,也就是说,它会在预定义的延迟后触发一个循环,每个循环都是循环的一次迭代,每次迭代都需要更新UI并更新迭代器值。

现在,因为我不喜欢在static 上下文中工作,所以我建议的第一件事是将基本概念包装到一个单独的类中。这样你就可以轻松封装状态

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();
    }

}

所以,这是非常基本的,所有这一切都是,使用Timer,检查是否还有需要打印的字符,如果有,它会获取下一个字符并将其附加到文本区域并更新迭代器值。如果我们在文本的末尾,它将停止Timer(即退出条件)

【讨论】:

  • 非常感谢您的快速回复,并提供了一个工作示例。开始时,这会将文本区域设置为 null,我假设可以安全地忽略此行为?
  • @BenKramer 它将“文本”设置为null,是的,当您想要清除文本组件时,这是一种常见的做法。您可以使用"" 获得相同的结果;由于文本组件的工作方式,它们永远不会从getText返回null
  • 我尝试创建两个在 synchronized 关键字下管理的实例,如下所示: synchronized(messageArea){ new TypeWriter(messageArea,"Testing").start(); new TypeWriter(messageArea,"“在宇宙被创造之初,这让很多人非常\nang,被广泛认为是一个糟糕的举动。”-Douglas Adams").start();但这并不强迫每个人“等待轮到”
  • 不,我不这么认为。我会在TypeWriter 类中添加一个观察者模式,它可以生成“开始”/“停止”事件,然后我会启动第一个类,当它触发一个“停止”事件时,启动下一个,基本上是链接一个给对方
  • 我不擅长编程,这种方法对我来说似乎有点野心勃勃。有没有一种雄心勃勃的方法,即使效率较低,我也可以尝试?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-27
  • 2016-01-11
  • 2021-12-25
  • 1970-01-01
相关资源
最近更新 更多