我设法制作了一个打字机类,该类可以完成大部分工作。它将一次输出给它的一个字符一个字符串,在每个字符之间暂停,就好像它们是键入的一样,在句点之后暂停更长的时间。我现在遇到的问题是,当我使用此类时,它只能运行一次。当我两次(或多次)调用它时,它将尝试同时运行它们。这引起了主要问题。因此,我需要一种方法来运行该类的第一个实例,然后让每个后续实例等待“轮到我”,然后再开始。以下是预期结果和当前结果的示例。

import objectdraw.*; // Where active object comes from.
import javax.swing.JTextArea;

public class Typewriter extends ActiveObject {

  private JTextArea out;
  private String in;

  public Typewriter(String s, JTextArea output) {

    in = s;
    out = output;
    start();

  }

  public void run() {

    synchronized(out) {

      for(int i=0; i<in.length(); i++) {

        out.append(in.substring(i,i+1));
        if(in.charAt(i) == '.') {
          pause(30);
        } else {
          pause(200);
        }

      }

    }

  }

}

当前的:

代码:
新的打字机(“\nHello”,输出);
新的打字机(“\nWorld”,输出);

当前输出
HW ol elr ldo

期望的输出
Hello
World

显然,我从Typewriter类中遗漏了大部分代码。如果确实需要,可以将其发布。可以在here中找到ActiveObject的javadocs。这是我被教会线程的方式,我担心这可能是问题所在。

编辑:

根据下面的答案,我已经添加了synced(out)行,但是当我尝试运行代码时,我得到了nullpointerexception。
Exception in thread "main" java.lang.NullPointerException
    at objectdraw.ActiveObject.<init>(ActiveObject.java:239)
    at com.caldwellysr.TBA.Typewriter.<init>(Typewriter.java:11)
    at com.caldwellysr.TBA.Client.initGame(Client.java:78)
    at com.caldwellysr.TBA.Client.<init>(Client.java:66)
    at com.caldwellysr.TBA.Client.main(Client.java:24)

打字机第11行是构造函数的标题。
客户行78是我称为新打字机的位置(“Testing”,输出);其中输出是一个JTextArea
客户端行66是对initGame()的调用,其中包含Typewriter
客户端行24是JFrame构造函数。

最佳答案

看来ActiveObject继承自Thread类,并且异步运行,因此您不知道线程何时运行。当您创建2个ActiveObject实例时,这2个for循环不一定会一个接一个地运行。您看到的结果是您的文本区域同时被2个线程更新。

编辑:

您可以使用synced子句同步运行代码:

synchronized(out){
    for(int i=0; i<in.length(); i++) {
        out.append(in.substring(i,i+1));

        if(in.charAt(i) == '.') {
            pause(30);
        }
        else {
            pause(200);
        }
    }
}

09-05 00:36